【问题标题】:RecyclerView onClickListener Setup PerformanceRecyclerView onClickListener 设置性能
【发布时间】:2023-04-05 20:39:01
【问题描述】:

所以我第一次尝试为我的 RecyclerView 实现onClickListener,我一直想知道我所做的是否真的值得做。在我的应用程序中,我有不同的 Recycler Views,而且我不需要在大多数情况下同时使用 onClickListenersonLongClickListeners,所以我想这样做,这样我就不必同时实现它们我的.setOnItemClickListener。我基本上检查了哪个onClickListener 设置了枚举模式,然后据此我将我的听众设置为onCreateViewHolder。这样做是否有意义?或者我应该只实现两个监听器而不做我在代码中所做的事情?

public class FreindRecyclerViewAdapter extends RecyclerView.Adapter<FreindRecyclerViewAdapter.MyViewHolder> {

    private ClickListener clickListener ;
    private LongClickListener longClickListener;

    private Context context;
    private List<String> friends;
    private ListenerMode mode;

    public enum ListenerMode {NullMode, ShortClick, LongClick}

    public interface ClickListener {

        void onItemClick(int position, View v);

    }

    public interface LongClickListener {

        void onItemLongClick(int position, View v);

    }

    public void setOnItemClickListener(ClickListener clickListener) {
        this.clickListener = clickListener;
        mode = ListenerMode.ShortClick;
    }

    public void setOnLongItemClickListener(LongClickListener longItemClickListener) {
        this.longClickListener = longItemClickListener;
        mode = ListenerMode.LongClick;
    }

    public FreindRecyclerViewAdapter (Context context, List<String> friends) {

        this.context = context;
        this.friends = friends;
        this.mode = ListenerMode.NullMode;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view;
        view = LayoutInflater.from(context).inflate(R.layout.friend_item, viewGroup, false);
        final MyViewHolder myViewHolder = new MyViewHolder(view);

        if(mode == ListenerMode.ShortClick) {
            myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    clickListener.onItemClick(myViewHolder.getAdapterPosition(), view);
                }
            });
        } else if (mode == ListenerMode.LongClick) {

            myViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {

                    longClickListener.onItemLongClick(myViewHolder.getAdapterPosition(), view);

                    return true;
                }
            });

        }



        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int position) {

        myViewHolder.friendName.setText(friends.get(position));


    }

    @Override
    public int getItemCount() {
        return friends.size();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {

        private TextView friendName;

        public MyViewHolder(View itemView) {
            super(itemView);

            friendName= itemView.findViewById(R.id.friendName_ID);

        }

    }

}

编辑:现在我想起来了,我什至不知道它为什么会起作用,比如当我在下面的代码中设置我的 RecyclerView、适配器和所有内容时,我首先告诉关于我想在它的构造函数recyclerViewAdapter = new FreindRecyclerViewAdapter(this, friends); 中显示在屏幕上的列表的适配器,所以这是我的视图调用onCreateViewHolder 的时候。所以现在当一切都被创建(ViewHolders)时,我调用该函数来设置 OnClickListener,它在我的代码中根据设置的mode 添加不同的侦听器,并且这些侦听器添加到 onCreateViewHolder,这已经调用,那么为什么 RecyclerViewAdapter(以及它如何知道)再次调用 onCreateViewHolder 来添加侦听器?

friends = new ArrayList<>();

        friends.add("Josh");
        friends.add("Mike");
        friends.add("Ashley");
        friends.add("Jess");


        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        recyclerView = findViewById(R.id.recyclerViewFriend_ID);
        recyclerViewAdapter = new FreindRecyclerViewAdapter(this, friends);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(recyclerViewAdapter);

        DividerItemDecoration itemDecor = new DividerItemDecoration(this, linearLayoutManager.getOrientation());
        recyclerView.addItemDecoration(itemDecor);



        recyclerViewAdapter.setOnLongItemClickListener(new FreindRecyclerViewAdapter.LongClickListener() {
            @Override
            public void onItemLongClick(int position, View v) {
                Toast.makeText(FriendActivity.this, "Long Click. Position:" + Integer.toString(position), Toast.LENGTH_SHORT).show();
            }
        });

【问题讨论】:

    标签: android android-recyclerview onclick onclicklistener


    【解决方案1】:

    没关系,但可以更好。

    1) 您正在为每个位置创建点击监听器和长按监听器

    您不需要像在这里所做的那样为每个位置创建一个侦听器:

    myViewHolder.itemView.setOnClickListener(new View.OnClickListener() ...
    
    and
    
    myViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() ...
    

    由于他们执行非常相似的操作,您可以只创建一个单击和长按侦听器并与所有视图共享。为此,请将itemView.setOnClickListener()itemView.setOnLongClickListener() 移至ViewHolder 类。

    您还需要将位置保存在 ViewHolder 中。因此,他们将能够存储自己的位置。

    2) 您不需要创建枚举

    您无需创建枚举来检查当前模式(单击或长按)。相反,您可以只检查变量是否为空。

    最后,你可以有这样的代码:

    public class FreindRecyclerViewAdapter extends RecyclerView.Adapter<FreindRecyclerViewAdapter.MyViewHolder> {
    
        private ClickListener clickListener ;
        private LongClickListener longClickListener;
    
        private Context context;
        private List<String> friends;
    
        public interface ClickListener {
            void onItemClick(int position, View v);
        }
    
        public interface LongClickListener {
            void onItemLongClick(int position, View v);
        }
    
        public void setOnItemClickListener(ClickListener clickListener) {
            this.clickListener = clickListener;
        }
    
        public void setOnLongItemClickListener(LongClickListener longItemClickListener) {
            this.longClickListener = longItemClickListener;
        }
    
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            View view;
            view = LayoutInflater.from(context).inflate(R.layout.friend_item, viewGroup, false);
            return new MyViewHolder(view, i, clickListener, longClickListener);;
        }
    
        @Override
        public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int position) {
            myViewHolder.friendName.setText(friends.get(position));
        }
    
        @Override
        public int getItemCount() {
            return friends.size();
        }
    
        public class MyViewHolder extends RecyclerView.ViewHolder implements
                View.OnLongClickListener, View.OnClickListener {
    
            private TextView friendName;
            private int position;
    
            public MyViewHolder(View itemView, int position) {
                super(itemView);
                friendName = itemView.findViewById(R.id.friendName_ID);
                this.position = position;
                if (clickListener != null) {
                    itemView.setOnClickListener(this);
                }
                if (longClickListener != null) {
                    itemView.setOnLongClickListener(this);
                }
            }
    
            @Override
            public void onClick(View view) {
                if (clickListener != null) {
                    clickListener.onItemClick(position, view);
                }
            }
    
            @Override
            public boolean onLongClick(View view) {
                if (longClickListener != null) {
                    longClickListener.onItemLongClick(position, view);
                    return true;
                } else {
                    return false;
                }
            }
        }
    }
    
    • 请注意,现在每个视图持有者都知道自己的位置
    • 视图持有者实现了常规的View.OnClickListenerView.LongClickListener。因此,您无需为每个位置都实例化一个新的侦听器。
    • 如果要启用点击,请致电FreindRecyclerViewAdapter.setOnItemClickListener(object);
    • 如需开启长按,请致电FreindRecyclerViewAdapter.setOnLongItemClickListener(object);
    • 如果你想禁用它们中的任何一个,不要调用上面的方法或者只是通过null作为参数调用它们。如果你检查MyViewHolder中的代码,你可以看到当这些监听器为空时执行了任何操作

    希望我能提供帮助并分享更多实现您想要的方法!!!

    【讨论】:

    • 是不是return new MyViewHolder(view, i)中的i变量实际上不是位置,根据google文档ionCreateViewHolder是ViewType,只有onBindViewHolderi是我在代码中重命名的位置。而且我对没有创建很多 onClickListeners 有点困惑,你说实现 onClickListenerViewHolder 避免创建多个侦听器,但这条线 return new MyViewHolder(view, i) 不是为每个基本上创建新的视图创建新的 ViewHolder onClickListener(本身)用它吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多