2016-04-19 1 views
8

У меня есть RecycleView с адаптером, который отображает список серверов , и пользователь должен выбрать один сервер.notifyItemChanged() сделать прокрутку RecyclerView и перейти к UP

, когда я называю notifyItemChanged (previousPosition) внутри метода OnClick(), чтобы сделать старый сервер невыбранные и новый сервер выбран, , что сделаем прыжок список RecycleView к вверх точно в середине списка.

и эта проблема случается только тогда, когда я нажимаю на одном из последних 2-х или 3-х серверов внутри списка RecycleView

вот код моего 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; 
     } 
    } 
} 

любые решения для решения Эта проблема ? Благодарю.

Проблема произошло именно тогда, когда я указать высоту макета и не позволяют ему wrap_content

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

или когда я положил его под что-то для expample как то:

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

мой код точно является:

<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

почему notifyItemChanged (previousSelected); ??? –

+0

, потому что я хочу, чтобы этот предыдущий вид был выбран как невыбранный, , если бы я не все его серверы будут отображаться как выбрано , потому что, когда я позвоню notifyItemChanged в эту старую позицию, он будет вызывать onBindViewHolder, и он проверит, эта позиция совпадает с номером, хранящимся в выбранном здесь целочисленном значении if (position == selected) { holder.getBackground(). setSelected (true); } else { holder.getBackground(). SetSelected (false); } –

+0

@OulhafianeZakariaa quick note -> backtick around code, имена методов улучшают читаемость (например, 'this' -> 'this') –

ответ

2

Я не знаю, почему, но я использовал:

RecyclerView.setHasFixedSize(true) 

Это сработало для меня. Надеюсь, это поможет.

+0

не работал для меня –

+0

Does не работает для меня тоже. – clocksmith

10

Похоже, это ошибка: https://code.google.com/p/android/issues/detail?id=203574

Лучший обходной путь, кажется, ответ Барта установить свойство AutoMeasure в RecyclerView в LinearLayoutManager к ложным.

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

Множество FixedSize к истинному решению было слишком много побочных эффектов ...

RecyclerView.setHasFixedSize (истинный)

+4

Это не работает для меня. Вместо этого все мои взгляды в RecyclerView исчезают. – clocksmith

+0

Решил мою проблему. Это должен быть принятый ответ! –

+0

после многих поисков это только решение, спасибо вам большое –

0

я наткнулся на аналогичной проблемой, просто взять уход за файлом макета xml.
Не используйте layout_below, layout_above или другие подобные свойства в представлении родителей RecyclerView или RecyclerView.
Вы можете использовать LinearLayout weight, layout_marginBottom или sth для достижения
layout_below или другой.

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

для тех, кто натыкается на этот вопрос, попробуйте использовать

yourRecyclerView.notifyItemChanged(int position, Object payload); 

Этот один сделал трюк для меня.

Использование

setAutoMeasureEnabled(false); 

также работал, но в некоторых случаях края зрения переработчик действовал странно. Удачи!