notifyItemChanged()使RecyclerView滚动并跳转到UP

我有一个适配器的RecycleView显示服务器列表,用户必须select一个服务器。

当我在onClick()方法内调用notifyItemChanged(previousPosition)来使旧的服务器被取消select,并select新的服务器时,这就使得RecycleView列表完全跳到列表中间。

当我点击RecycleView列表中的最后2个或3个服务器之一时,就会发生这个问题

这里是我的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; } } } 

任何解决scheme来解决这个问题? 谢谢。

这个问题恰好发生在我指定布局高度的时候,不要让它到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"/> 

Solutions Collecting From Web of "notifyItemChanged()使RecyclerView滚动并跳转到UP"

看起来像这是一个错误: https : //code.google.com/p/android/issues/detail?id=203574

最好的解决方法似乎是巴特的答案将RecyclerView的LinearLayoutManager的AutoMeasure属性设置为false。

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

设置FixedSize为真解决scheme有太多的副作用…

RecyclerView.setHasFixedSize(真)

我不知道为什么,但我用:

 RecyclerView.setHasFixedSize(true) 

这对我有效。 我希望它可以帮助。

对于任何人在这个问题上绊倒,尝试使用

 yourRecyclerView.notifyItemChanged(int position, Object payload); 

这个为我做了诡计。

运用

 setAutoMeasureEnabled(false); 

也工作,但在一些边缘情况下,回收者的观点是奇怪的。 祝你好运!

我碰到类似的问题,只是照顾的XML布局文件。
不要在RecyclerView或RecyclerView的父视图中使用layout_belowlayout_above或其他类似的属性。
你可以使用LinearLayout weightlayout_marginBottom或者sth来实现
layout_below或其他。

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