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

Zak*_*ane 12 android recycler-adapter android-recyclerview

我有一个带有适配器的RecycleView,它显示了一个服务器列表,用户必须选择一个服务器.

当我在onClick()方法中调用notifyItemChanged(previousPosition)以使旧服务器未被选中并选择新服务器时,这使得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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

解决这个问题的任何解决方案?谢谢.

当我指定布局高度并且不让它为wrap_content时,问题恰好发生了

<android.support.v7.widget.RecyclerView
    android:layout_width="wrap_content"
    android:layout_height="400dp"
    android:id="@+id/serverRecyclerView"
    android:layout_margin="10dp"
/>
Run Code Online (Sandbox Code Playgroud)

或者当我把它放在下面这样的东西时:

<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"/>
Run Code Online (Sandbox Code Playgroud)

我的代码完全是:

<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"/>
Run Code Online (Sandbox Code Playgroud)

Aac*_*ace 13

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

最好的解决方法似乎是Bart的回答,将RecyclerView的LinearLayoutManager的AutoMeasure属性设置为false.

  LinearLayoutManager llm = new LinearLayoutManager(context);
  llm.setAutoMeasureEnabled(false);       
  recyclerView.setLayoutManager(llm);
Run Code Online (Sandbox Code Playgroud)

将FixedSize设置为true解决方案有太多副作用......

RecyclerView.setHasFixedSize(真)

  • 这对我不起作用.相反,我在RecyclerView中的所有视图都消失了. (4认同)
  • 现在 setAutoMeasureEnabled(false) 方法已弃用 (2认同)

zzq*_*zzq 8

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

RecyclerView.setHasFixedSize(true)
Run Code Online (Sandbox Code Playgroud)

这对我有用。我希望它能有所帮助。


小智 5

 android:descendantFocusability="blocksDescendants"
Run Code Online (Sandbox Code Playgroud)

android:descendantFocusability =“ blocksDescendants”

这个attr解决了我的错误

  • 垂直 recyclerView 内的水平 recyclerView 通常会导致该问题,这是解决问题的最佳方法。不要将此属性放入水平 recyclerViews 中,它只需要位于 Parent(vertical RecyclerView) 中 (2认同)