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

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

问题描述

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

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

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

这是我的 RecyclerView.Adapter 的代码:

public class ServerAdapter extends RecyclerView.Adapter{私有列表<服务器>listServers = new ArrayList<>();private int[] 图标 = new int[]{R.drawable.server1,R.drawable.server2,R.drawable.server3,R.drawable.server4,R.drawable.server5,R.drawable.server6,R.drawable.离线};选择的私有整数 = 0;私人诠释previousSelected = 0;公共服务器适配器(列表<服务器>列表服务器){this.listServers = listServers;}@覆盖public ServerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {查看视图 = LayoutInflater.from(parent.getContext()).inflate(R.layout.server_relative_layout,parent,false);返回新的 ServerViewHolder(view);}@覆盖公共无效 onBindViewHolder(最终 ServerViewHolder 持有人,最终 int 位置){如果(位置 == 选择){holder.getBackground().setSelected(true);}别的{holder.getBackground().setSelected(false);}holder.getBackground().setOnClickListener(new View.OnClickListener() {@覆盖public void onClick(View v) {如果(位置!=选择){上一个选择 = 选择;选择 = 位置;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());}@覆盖公共 int getItemCount() {返回 listServers.size();}公共类 ServerViewHolder 扩展 RecyclerView.ViewHolder{私有 ImageView 图像服务器;私有 TextView 文本名称服务器;私有 TextView 文本连接;私人查看背景;公共 ServerViewHolder(查看 itemView){超级(项目视图);imageServer = (ImageView)itemView.findViewById(R.id.imageServer);textNameServer = (TextView)itemView.findViewById(R.id.textNameServer);textConnected = (TextView)itemView.findViewById(R.id.textConnected);背景 = 项目视图;}公共 ImageView getImageServer() {返回图像服务器;}公共 TextView getTextConnected() {返回 textConnected;}公共 TextView getTextNameServer() {返回文本名称服务器;}公共视图 getBackground() {返回背景;}}}

有什么办法可以解决这个问题?谢谢.

问题恰好发生在我指定布局高度并且不让它到 wrap_content 时

或者当我把它放在下面的例子中时:

我的代码正是:

解决方案

看起来这是一个错误: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);

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

RecyclerView.setHasFixedSize(true)

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

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.

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

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

my code exactly is :

<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

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);

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

RecyclerView.setHasFixedSize(true)

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

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