2016-04-19 24 views
8

Mam RecycleView z adapterem, który pokazuje listę serwerów i użytkownik musi wybrać jeden serwer.notifyItemChanged() sprawiają, że RecyclerView przewijać i przejść do UP

gdy zgłoszę notifyItemChanged (previousPosition) wewnątrz metody onClick(), aby stary serwer odznaczone i nowy serwer wybrany, to zrobić listę RecycleView skokiem się dokładnie w środku listy.

i ten problem zdarzyć tylko po kliknięciu na jednym z ostatnich 2 lub 3 serwerów wewnątrz listy RecycleView

Oto kod mojego 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; 
     } 
    } 
} 

wszelkie rozwiązania do rozwiązania ten problem ? dzięki.

Problemem stało, kiedy dokładnie określić wysokość układu i nie pozwól, aby wrap_content

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

lub kiedy kładę go poniżej coś dla expample tak:

<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"/> 

mój kod dokładnie jest:

<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

dlaczego notifyItemChanged (previousSelected); ??? –

+0

ponieważ chcę, aby ten poprzedni widok został zaznaczony jako niezaznaczony, , jeśli nie wszystkie serwery będą pokazywane jako wybrane , ponieważ kiedy zadzwonię notifyItemChanged do tej starej pozycji zadzwoni onBindViewHolder i sprawdzi czy ta sytuacja jest taka sama jak numer przechowywane w liczbą całkowitą o jeśli (pozycja == wybrane) { holder.getBackground() setSelected (prawda.); } else { właściciel.getBackground(). SetSelected (false); } –

+0

@OulhafianeZakariaa szybkie uwaga -> grawis wokół kodowych, nazw metoda poprawia czytelność (jak to '' -> 'this') –

Odpowiedz

2

nie wiem dlaczego, ale kiedyś:

RecyclerView.setHasFixedSize(true) 

To zadziałało dla mnie. Mam nadzieję, że to pomoże.

+0

nie pracował dla mnie –

+0

robi nie działa też dla mnie. – clocksmith

10

Wygląda na to, że jest to błąd: https://code.google.com/p/android/issues/detail?id=203574

Najlepszym Rozwiązaniem wydaje się być odpowiedzią Barta ustawić właściwość AutoMeasure w RecyclerView za LinearLayoutManager do fałszywe.

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

Zestaw fixedSize do prawdziwego rozwiązania miał zbyt wiele skutków ubocznych ...

RecyclerView.setHasFixedSize (true)

+4

To nie działa dla mnie. Zamiast tego wszystkie moje widoki w widoku RecyclerView znikają. – clocksmith

+0

Rozwiązałem mój problem. To powinna być zaakceptowana odpowiedź! –

+0

po wielu poszukiwaniach to tylko rozwiązanie, dziękuję bardzo –

0

natknąłem się na podobny problem, po prostu wziąć dbanie o plik układu XML.
Nie używaj layout_below, layout_above lub innych podobnych właściwości w widoku nadrzędnym RecyclerView lub RecyclerView.
Możesz użyć LinearLayout weight, layout_marginBottom lub czegoś, aby uzyskać
layout_below lub inną.

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

dla każdego, kto natyka się na ten problem, spróbuj użyć

yourRecyclerView.notifyItemChanged(int position, Object payload); 

ten jeden nie załatwi dla mnie.

Korzystanie

setAutoMeasureEnabled(false); 

również pracował, ale w niektórych przypadkach krawędzi widok recyklingowa było dziwnie. Powodzenia!