[英]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.