2016-04-19 13 views
8

Ho un RecycleView con un adattatore che mostra un elenco di server e l'utente deve selezionare un server.notifyItemChanged() fa scorrere RecyclerView e passa a UP

quando chiamo notifyItemChanged (previousPosition) all'interno del metodo onClick() per rendere il vecchio server non selezionato e il nuovo server selezionato, che di fare l'elenco RecycleView salto per esattamente nel mezzo della lista.

e questo problema accada proprio quando clicco su uno degli ultimi 2 o 3 server all'interno della lista RecycleView

Ecco il codice della mia RecyclerView.Adapter:

public class ServerAdapter extends RecyclerView.Adapter<ServerAdapter.ServerViewHolder> { 

    private List<Server> listServers = new ArrayList<>(); 
    private int[] icons = new int[]{R.drawable.server1,R.drawable.server2,R.drawable.server3,R.drawable.server4,R.drawable.server5,R.drawable.server6,R.drawable.offline}; 
    private int selected = 0; 
    private int previousSelected = 0; 

    public ServerAdapter(List<Server> listServers){ 
     this.listServers = listServers; 
    } 

    @Override 
    public ServerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.server_relative_layout,parent,false); 
     return new ServerViewHolder(view); 
    } 

    @Override 
    public void onBindViewHolder(final ServerViewHolder holder, final int position) { 
     if(position == selected){ 
      holder.getBackground().setSelected(true); 
     }else{ 
      holder.getBackground().setSelected(false); 
     } 
     holder.getBackground().setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if(position != selected){ 
        previousSelected = selected; 
        selected = position; 
        holder.getBackground().setSelected(true); 
        notifyItemChanged(previousSelected); 
       } 
      } 
     }); 
     holder.getImageServer().setImageResource(icons[position%6]); 
     holder.getTextNameServer().setText(listServers.get(position).getName()); 
     holder.getTextConnected().setText(listServers.get(position).getUrl()); 
    } 

    @Override 
    public int getItemCount() { 
     return listServers.size(); 
    } 

    public class ServerViewHolder extends RecyclerView.ViewHolder{ 
     private ImageView imageServer; 
     private TextView textNameServer; 
     private TextView textConnected; 
     private View background; 
     public ServerViewHolder(View itemView) { 
      super(itemView); 
      imageServer = (ImageView)itemView.findViewById(R.id.imageServer); 
      textNameServer = (TextView)itemView.findViewById(R.id.textNameServer); 
      textConnected = (TextView)itemView.findViewById(R.id.textConnected); 
      background = itemView; 
     } 

     public ImageView getImageServer() { 
      return imageServer; 
     } 

     public TextView getTextConnected() { 
      return textConnected; 
     } 

     public TextView getTextNameServer() { 
      return textNameServer; 
     } 

     public View getBackground() { 
      return background; 
     } 
    } 
} 

eventuali soluzioni per risolvere questo problema ? Grazie.

Il problema è accaduto esattamente quando ho specificare l'altezza di layout e non lasciarlo a wrap_content

<android.support.v7.widget.RecyclerView 
    android:layout_width="wrap_content" 
    android:layout_height="400dp" 
    android:id="@+id/serverRecyclerView" 
    android:layout_margin="10dp" 
/> 

o quando ho messo sotto qualcosa per expample del genere:

<android.support.v7.widget.RecyclerView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/serverRecyclerView" 
    android:layout_margin="10dp" 
    android:layout_below="@+id/image"/> 

il mio codice esattamente è:

<android.support.v7.widget.RecyclerView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/serverRecyclerView" 
    android:layout_margin="10dp" 
    android:layout_alignTop="@+id/imageBall" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentEnd="true" 
    android:layout_toRightOf="@+id/camera" 
    android:layout_toEndOf="@+id/camera"/> 
+0

perché notifyItemChanged (previousSelected); ??? –

+0

perché voglio che questa vista precedente selezionata venga mostrata come non selezionata, se non l'ho fatto tutti i server verranno mostrati come selezionati perché quando chiamerò notifyItemChanged su questa vecchia posizione chiamerà suBindViewHolder e controllerà se questa posizione è uguale al numero memorizzato nel numero intero selezionato qui if (posizione == selezionato) { holder.getBackground(). setSelected (true); } else { holder.getBackground(). SetSelected (false); } –

+0

@OulhafianeZakariaa nota rapida -> backtick intorno al codice, i nomi dei metodi migliorano la leggibilità (come 'questo' -> 'questo') –

risposta

2

non so perché, ma ho usato:

RecyclerView.setHasFixedSize(true) 

Questo ha funzionato per me. Spero possa aiutarti.

+0

non ha funzionato per me –

+0

non funziona neanche per me. – clocksmith

10

Sembra questo un bug: https://code.google.com/p/android/issues/detail?id=203574

La soluzione migliore sembra essere la risposta di Bart per impostare la proprietà Misurazione automatica del del RecyclerView LinearLayoutManager false.

LinearLayoutManager llm = new LinearLayoutManager(context); 
    llm.setAutoMeasureEnabled(false);  
    recyclerView.setLayoutManager(llm); 

La FixedSize insieme alla vera soluzione doveva troppi effetti collaterali ...

RecyclerView.setHasFixedSize (vero)

+4

Questo non funziona per me. Invece, tutte le mie viste all'interno di RecyclerView scompaiono. – clocksmith

+0

Risolto il mio problema. Dovrebbe essere la risposta accettata! –

+0

dopo molte ricerche questa è solo una soluzione, grazie mille –

0

mi sono imbattuto nel problema simile, basta prendere cura del file di layout xml.
Non utilizzare layout_below, layout_above o altre proprietà simili nella vista principale di RecyclerView o RecyclerView.
È possibile utilizzare LinearLayout weight, layout_marginBottom o sth per raggiungere
layout_below o altro.

0
RecyclerView.ItemAnimator animator = myRecyclerListView.getItemAnimator(); 
if (animator instanceof SimpleItemAnimator) { 
    ((SimpleItemAnimator)animator).setSupportsChangeAnimations(false); 
} 
1

per chi si imbatte in questo problema, provare a utilizzare

yourRecyclerView.notifyItemChanged(int position, Object payload); 

questo fatto il trucco per me.

Utilizzando

setAutoMeasureEnabled(false); 

anche lavorato ma in alcuni casi limite vista riciclatore è stata comporta in modo strano. In bocca al lupo!

Problemi correlati