android - RecyclerView onClickListener 设置性能

标签 android android-recyclerview onclick onclicklistener

所以我第一次尝试为我的 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 以获取我的 View 的时间。所以现在当一切都被创建时(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();
            }
        });

最佳答案

还可以,但可以做得更好。

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

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

myViewHolder.itemView.setOnClickListener(new View.OnClickListener() ...

and

myViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() ...

由于它们执行的操作非常相似,因此您可以只创建一个单击和长按监听器并与所有 View 共享。为此,将 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 持有者都知道自己的位置
  • View holder 实现常规的 View.OnClickListenerView.LongClickListener。因此,您不需要为每个位置都实例化一个新的监听器。
  • 如果你想启用点击,调用FreindRecyclerViewAdapter.setOnItemClickListener(object);
  • 如果你想启用长按,调用FreindRecyclerViewAdapter.setOnLongItemClickListener(object);
  • 如果您想禁用它们中的任何一个,请不要调用上述方法或仅将 null 作为参数传递给它们。如果您检查 MyViewHolder 中的代码,您可以看到当这些监听器为 null 时执行任何操作

希望我能帮助和分享更多的方法来实现你想要的!!!

关于android - RecyclerView onClickListener 设置性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53015877/

相关文章:

java - 如何查找位于 3D 边界内的点

android - 如何添加线性布局始终是 RecyclerView 中的第一个元素?

Android EditText AND SearchView : What are the main differences (except the design)?

javascript - 如何显示 jqplot 图表区域的值而不是百分比

javascript - onClick之后的渲染组件

c# - 从 C# 调用 onclick 方法

android - 我如何使用至少一个特殊字符、数字、大写小写字母验证我的密码,但用户输入允许 4 个中的任意三个?

java - 当我尝试比较数据库中的值和编辑文本输入时,出现 NullPointerException

android - iqengines 演示应用程序崩溃

java - 如何在 RecyclerView 中设置 stackFromBottom?