RecyclerView中EditText和ImageView的ViewHolder復用坑
RecyclerView作為ListView的升級版,目前來講講開發過程遇到的坑。
- RecyclerView 中使用 EditText 滾動后數據消失,錯亂
場景:RecyclerView中的每個Item的ViewHolder布局中為都有EditText控件,且ViewHolder實現文本改變監聽器TextWatcher,用來在用戶輸入后將數據取出寫入到 列表數據中。
添加文本后,上下滑動RecyclerView且將Item劃出屏幕。如:填寫此EditText為1后,滑出屏幕滑回,文本可能變成0后或其他
結果:對應位置上的EditText未能顯示Adapter數據集中對應位置的Text
public static
abstract class BaseViewHolder<Data> extends RecyclerView.ViewHolder{/*** 構造** @param itemView 初始化根布局*/public BaseViewHolder(View itemView) {
super(itemView);itemView.setLayoutParams(
new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT,RecyclerView.LayoutParams.WRAP_CONTENT));}
/*** 適配器刷新子項回調* @param data*/public
abstract void onRefreshView(Data data,int position);public
final <T> T findViewById(int resId){
return (T) itemView.findViewById(resId);}}
public class ViewHolderContentText extends RecyclerViewBaseAdapter.BaseViewHolder<ArticleContentBean> implementsTextWatcher, {private static final int VIEW_TYPE=
3;
public EditText contentText;
public ViewHolderContentText(View itemView) {
super(itemView);contentText= (EditText) itemView.findViewById(R.id.et_text);quoteLine=itemView.findViewById(R.id.v_quote_line);contentText.addTextChangedListener(
this);}@Override
public void onRefreshView(ArticleContentBean articleContentBean,
int position){String text=textBean.getContentText();contentText.setText(text);}@Override
public void beforeTextChanged(CharSequence s,
int start,
int count,
int after) {}@Override
public void onTextChanged(CharSequence s,
int start,
int before,
int count) {}@Override
public void afterTextChanged(Editable s) {}
}
原因:
????乍一看這段代碼沒有什么問題,但實際上這里有一個很大的坑。通過在 afterTextChanged 方法上增加 Log 記錄可以發現,該方法會被多次的調用,其根本原因是因為 EditText 的被重新復用,并且重新繪制!當重繪之后 該回調函數沒有獲取到填充的數據,還是原來復用的數據。
解決辦法:每次填充數據之前先移除 TextWatcher 監聽器,然后為 EditText 填充數據 ,最后在為 EditText 添加 TextWatcher 監聽器,
public class ViewHolderContentText extends RecyclerViewBaseAdapter.BaseViewHolder<ArticleContentBean> implementsTextWatcher, {private static final int VIEW_TYPE=
3;
public EditText contentText;
public ViewHolderContentText(View itemView) {
super(itemView);contentText= (EditText) itemView.findViewById(R.id.et_text);quoteLine=itemView.findViewById(R.id.v_quote_line);}@Override
public void onRefreshView(ArticleContentBean articleContentBean,
int position){
if (contentText.getTag(R.id.tag_textWatcher_data) instanceof TextWatcher){contentText.removeTextChangedListener(
this);}String text=textBean.getContentText();contentText.setText(text);contentText.addTextChangedListener(
this);contentText.setTag(R.id.tag_textWatcher_data,
this);}@Override
public void beforeTextChanged(CharSequence s,
int start,
int count,
int after) {}@Override
public void onTextChanged(CharSequence s,
int start,
int before,
int count) {}@Override
public void afterTextChanged(Editable s) {}
}
- RecyclerView 中使用 ImageView滾動后圖片閃爍,圖片切換明顯
場景:
????RecyclerView 的Item布局中都包含ImageView,加載圖片使用Glide加載,當ImageView填充圖片之后,滑出屏幕在滑回,回看見圖片回閃一下,或者先顯示上一張圖片瞬間切換到應該顯示的圖片,切換明顯
原因:
????因為RecyclerView 的ViewHolder復用,當顯示該圖片時,在RecyclerView 的holder復用池中取出一個之前的Holder顯示該圖片,但是此Holder還持有之前的圖片,所以如果該圖片和此Holder持有的圖片相同就閃爍,不同就會有明顯的切換。
解決方案:
????將數據綁定到ViewHolder的Tag,當刷新數據時,判斷此ViewHolder的Tag的之前綁定的數據與當前數據比較,相同就不刷新數據,不相同就使用Glide的placeholder墊一個白色或無色圖
public class ViewHolderContentPhoto extends RecyclerViewBaseAdapter.BaseViewHolder<ArticleContentBean> {private static final int VIEW_TYPE=
4;
public ImageView contentPhoto;
public ViewHolderContentPhoto(View itemView) {
super(itemView);contentPhoto= findViewById(R.id.iv_insert_photo);}@Override
public void onRefreshView(
final ArticleContentBean articleContentBean,
final int position) {ArticleContentBean dataBefore= contentPhoto.getTag(R.id.tag_item_data);
if (dataBefore!=
null&&dataBefore.equals(articleContentBean)){
return;}String path = dataBefore.getPath();Glide.with(context).load(path).diskCacheStrategy(DiskCacheStrategy.ALL).crossFade().placeholder(
new ColorDrawable(Color.TRANSPARENT)).into(contentPhoto);contentPhoto.setTag(R.id.tag_item_data,articleContentBean);}}
參考鏈接:
1.踩坑記-在 RecyclerView 中使用 EditText 滾動后數據消失
2. RecyclerView中使用EditText
3.小心!Listview結合EditText使用實例中遇到的那些坑
總結
以上是生活随笔為你收集整理的Android踩坑日记:RecyclerView中EditText和ImageView的ViewHolder复用坑的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。