首页 > 解决方案 > RecyclerView onClickListener 设置性能

问题描述

所以我第一次尝试onClickListener为我的 RecyclerView 实现,我一直想知道我所做的是否真的值得做。在我的应用程序中,我有不同的 Recycler 视图,而且我不需要同时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、适配器和所有内容时,我首先告诉适配器我想在screen 在它的构造函数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();
            }
        });

标签: androidandroid-recyclerviewonclickonclicklistener

解决方案


没关系,但它可以更好。

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,您可以看到当这些侦听器为空时执行了任何操作

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


推荐阅读