编辑:
我想知道在bindViewHolder
方法中创建匿名侦听器会导致大数据集出现任何性能问题。
假设我有一个 RecyclerView 适配器。并且在bindViewHolder
方法中,如果我匿名设置所有监听器,这会导致任何性能问题吗?因为当用户滚动RecyclerView时,它将创建许多匿名侦听器并将它们设置为视图。
示例:
view.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
}
});
或者我可以在我的ViewHolder类中实现OnClickListener
,只需添加到views.Like
view.setOnClickListener(this);
这里没有创建很多匿名听众。对于大型数据集,这在以前的性能计算中表现更好吗?
提前致谢。
答案 0 :(得分:1)
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);
}
答案 1 :(得分:0)
基本上,您在OnClickListener
和" connect"的每个项目中都设置了RecyclerView
。它是Activity
或Fragment
。这个"连接"很重要,因此您可以在onItemClick
或Activity
中使用Fragment
方法并访问其中的成员。
最小的实现看起来像这样(在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());
}
}
}
}
答案 2 :(得分:0)
我很确定编译器只会在你的匿名类中创建一个无名的具体版本。这几乎与实现接口并将this
作为具体监听器相同。实际上,你不应该遇到性能问题。
请记住,匿名类包含对外部类的引用。这可能会造成内存泄漏(例如:如果外部类是一个活动),或者只是让它一次性发生垃圾收集而不是小块。有关详细信息,请参阅oracle文档中的Implicit and Synthetic Parameters。