android - RecyclerView onClickListener 设置性能
问题描述
所以我第一次尝试onClickListener
为我的 RecyclerView 实现,我一直想知道我所做的是否真的值得做。在我的应用程序中,我有不同的 Recycler 视图,而且我不需要同时onClickListeners
在onLongClickListeners
其中的大多数视图中,所以我想这样做,这样我就不必在我的.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();
}
});
解决方案
没关系,但它可以更好。
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.OnClickListener
和View.LongClickListener
. 因此,您不需要为每个位置都实例化一个新的侦听器。 - 如果要启用点击,请致电
FreindRecyclerViewAdapter.setOnItemClickListener(object);
- 如果要启用长按,请致电
FreindRecyclerViewAdapter.setOnLongItemClickListener(object);
- 如果你想禁用它们中的任何一个,不要调用上面的方法或者只是调用它们
null
作为参数传递。如果您检查代码MyViewHolder
,您可以看到当这些侦听器为空时执行了任何操作
希望我能提供帮助并分享更多实现您想要的方法!!!
推荐阅读
- python - Google Colab Error : Failed to get convolution algorithm.This is probably because cuDNN failed to initialize
- r - Replacing an element within a vector in a list
- sharepoint - 带有仅应用程序令牌的 Office 365 SharePoint API 返回 401
- c# - 在嵌入文档上应用过滤器后选择文档中的字段
- java - 如何在 Java 中始终如一地生成正确的 SHA-384 哈希字符串
- makefile - Makefile 找不到目标
- javascript - 如何在 .net 核心中将 Json 数据发布到没有模型的控制器
- powershell - 调用另一个带有参数验证的脚本
- spring-boot - 在 Spring Boot 应用程序中保护静态资源
- error-handling - Sequelize 模型重复值检查