[英]Anonymous Listener in RecyclerView Adapter
编辑:
我想知道在bindViewHolder
方法中创建匿名侦听器会导致任何性能问题或不会导致大型数据集。
假设我有一个RecyclerView适配器。 在bindViewHolder
方法中,如果我匿名设置所有侦听器,这会导致任何性能问题吗? 因为当用户滚动 RecyclerView 时,它会创建许多匿名侦听器并将它们设置为视图。
例子:
view.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
}
});
或者我可以在我的 ViewHolder 类中实现OnClickListener
并添加到 views.Like
view.setOnClickListener(this);
这里没有创建很多匿名侦听器。 在大型数据集的性能计算中,这是否比以前的性能更好?
提前致谢。
RecyclerView
只会显示很少的项目, ViewHolder
只会为可见的项目创建,因此即使您的适配器中有 1000 个项目,也只会创建一小部分ViewHolders
。
但是您必须小心使用addListener
方法,对于大多数setListener
方法,当项目被回收时,您将一次又一次地设置相同的侦听器,这不会少于几毫秒,因为它只保留侦听器实现的引用。
但是使用addListener
,您必须在添加新侦听器之前删除旧侦听器。
的例子setListener
是setClickListener
和举例addListener
是addTextWatcher
//.. part of adapter
private TextWatcher textWatcher;
public void bindViewHolder(DataViewHolder holder, int index){
// no performance issue
holder.button.setClickListener( .... );
// wrong, this is added everytime
holder.editText.addTextWatcher( .... );
// this is safe...
if(textWatcher != null)
holder.editText.removeTextWatcher(textWatcher);
textWatcher = new TextWatcher(){
// ... implementation
};
holder.editText.addTextWatcher(textWatcher);
}
基本上,您在RecyclerView
每个项目中设置一个OnClickListener
并将其“连接”到您的Activity
或Fragment
。 这种“连接”很重要,因此您可以在Activity
或Fragment
使用onItemClick
方法并访问那里的成员。
最小的实现如下所示(在Fragment
,但您也可以使用Activity
):
public class YourFragment extends Fragment implements RecyclerViewAdapter.ItemClickListener {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_your, container, false);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(activity);
recyclerViewAdapter.setClickListener(this);
recyclerView.setAdapter(recyclerViewAdapter);
return view;
}
@Override
public void onItemClick(View view, int position) {
// do something here
}
}
和Adapter
类
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private ItemClickListener itemClickListener;
void setClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
interface ItemClickListener {
void onItemClick(View view, int position);
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// TextView is an example
final TextView textView;
ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.text);
textView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (itemClickListener != null) {
itemClickListener.onItemClick(view, getAdapterPosition());
}
}
}
}
我很确定编译器只是在幕后创建了匿名类的无名具体版本。 这几乎等同于实现该接口并提供this
作为一个具体的监听器。 实际上,两者都不应该有性能问题。
请记住,匿名类持有对外部类的引用。 这可能会造成内存泄漏(例如:如果外部类是一个活动)或者只是让垃圾收集一次性发生,而不是随着时间的推移发生小块。 有关更多详细信息,请参阅 oracle 文档中的隐式和合成参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.