2015-11-15 48 views
8

我讀從谷歌的樣本代碼,該代碼是這樣的:應該保持對適配器的引用嗎?

public class AttractionListFragment extends Fragment { 
... 

private class AttractionAdapter extends RecyclerView.Adapter<ViewHolder> 
     implements ItemClickListener { 

    public List<Attraction> mAttractionList; 
    private Context mContext; 

    public AttractionAdapter(Context context, List<Attraction> attractions) { 
     super(); 
     mContext = context; 
     mAttractionList = attractions; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     Log.d("TEST", "onCreateViewHolder"); 
     LayoutInflater inflater = LayoutInflater.from(mContext); 
     View view = inflater.inflate(R.layout.list_row, parent, false); 
     return new ViewHolder(view, this); 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     Attraction attraction = mAttractionList.get(position); 

     holder.mTitleTextView.setText(attraction.name); 
     holder.mDescriptionTextView.setText(attraction.description); 
     Glide.with(mContext) 
       .load(attraction.imageUrl) 
       .diskCacheStrategy(DiskCacheStrategy.SOURCE) 
       .placeholder(R.drawable.empty_photo) 
       .override(mImageSize, mImageSize) 
       .into(holder.mImageView); 

     String distance = 
       Utils.formatDistanceBetween(mLatestLocation, attraction.location); 
     if (TextUtils.isEmpty(distance)) { 
      holder.mOverlayTextView.setVisibility(View.GONE); 
     } else { 
      holder.mOverlayTextView.setVisibility(View.VISIBLE); 
      holder.mOverlayTextView.setText(distance); 
     } 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public int getItemCount() { 
     return mAttractionList == null ? 0 : mAttractionList.size(); 
    } 

    @Override 
    public void onItemClick(View view, int position) { 
     View heroView = view.findViewById(android.R.id.icon); 
     DetailActivity.launch(
       getActivity(), mAdapter.mAttractionList.get(position).name, heroView); 
    } 
} 

private static class ViewHolder extends RecyclerView.ViewHolder 
     implements View.OnClickListener { 

    TextView mTitleTextView; 
    TextView mDescriptionTextView; 
    TextView mOverlayTextView; 
    ImageView mImageView; 
    ItemClickListener mItemClickListener; 

    public ViewHolder(View view, ItemClickListener itemClickListener) { 
     super(view); 
     mTitleTextView = (TextView) view.findViewById(android.R.id.text1); 
     mDescriptionTextView = (TextView) view.findViewById(android.R.id.text2); 
     mOverlayTextView = (TextView) view.findViewById(R.id.overlaytext); 
     mImageView = (ImageView) view.findViewById(android.R.id.icon); 
     mItemClickListener = itemClickListener; 
     view.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View v) { 
     mItemClickListener.onItemClick(v, getAdapterPosition()); 
    } 
} 

interface ItemClickListener { 
    void onItemClick(View view, int position); 
} 

}

你可以看到每一個ViewHolder持有引用(ItemClickListener)到適配器,由於適配器保持參考ViewHolder已經有人知道這種實現是否會導致內存泄漏?如果我的理解錯誤,請糾正我。

回答

0

不要以爲會這樣。 ViewHolder不能在沒有適配器的情況下存在,並且在適配器之前會很好地進行垃圾回收,因爲在RecyclerView滾動時,ViewHolders會不斷被適配器回收。正在使用的接口模式只是通知適配器某個ViewHolder已被點擊的常用方式。我想你可能會泄漏內存,如果你通過在適配器內的成員變量中持有對特定ViewHolder的引用來做相反的操作,那麼可能會阻止ViewHolder被GC_d調用。不過,上面的代碼看起來很標準。

相關問題