notifyItemChanged()使RecyclerView滚动并跳转到UP [英] notifyItemChanged() make the RecyclerView scroll and jump to UP

查看:463
本文介绍了notifyItemChanged()使RecyclerView滚动并跳转到UP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i have a RecycleView with an adapter that show a list of servers and the user must select one server.

当我在onClick()方法中调用notifyItemChanged(previousPosition)时 要取消选择旧服务器而选择新服务器, 这使得RecycleView列表完全跳到列表的中间.

when i call notifyItemChanged(previousPosition) inside the onClick() method to make the old server unselected and the new server selected, that's make the RecycleView list jump to up exactly in the middle of list.

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

and this problem happen just when i click on one of the last 2 or 3 servers inside the RecycleView list

这是我的RecyclerView.Adapter的代码:

here is the code of my 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;
        }
    }
}

有解决此问题的解决方案吗?谢谢.

any solutions to solve this problem ? thanks.

当我指定版面高度并且不让它包装内容时,问题就发生了

The problem happened exactly when i specify the layout height and do not let it to wrap_content

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

或者当我将其放在下面这样的示例时:

or when i put it below something for expample like that :

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

推荐答案

如下所示是一个错误:

Looks like this is a bug: https://code.google.com/p/android/issues/detail?id=203574

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

The best workaround seems to be Bart's answer to set the RecyclerView's LinearLayoutManager's AutoMeasure property to false.

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

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

The set FixedSize to true solution had way too many side-effects...

RecyclerView.setHasFixedSize(true)

RecyclerView.setHasFixedSize(true)

这篇关于notifyItemChanged()使RecyclerView滚动并跳转到UP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆