RecyclerView中EditText和ImageView的ViewHolder復(fù)用坑
RecyclerView作為L(zhǎng)istView的升級(jí)版,目前來講講開發(fā)過程遇到的坑。
- RecyclerView 中使用 EditText 滾動(dòng)后數(shù)據(jù)消失,錯(cuò)亂
場(chǎng)景:RecyclerView中的每個(gè)Item的ViewHolder布局中為都有EditText控件,且ViewHolder實(shí)現(xiàn)文本改變監(jiān)聽器TextWatcher,用來在用戶輸入后將數(shù)據(jù)取出寫入到 列表數(shù)據(jù)中。
添加文本后,上下滑動(dòng)RecyclerView且將Item劃出屏幕。如:填寫此EditText為1后,滑出屏幕滑回,文本可能變成0后或其他
結(jié)果:對(duì)應(yīng)位置上的EditText未能顯示Adapter數(shù)據(jù)集中對(duì)應(yīng)位置的Text
public static
abstract class BaseViewHolder<Data> extends RecyclerView.ViewHolder{/*** 構(gòu)造** @param itemView 初始化根布局*/public BaseViewHolder(View itemView) {
super(itemView);itemView.setLayoutParams(
new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT,RecyclerView.LayoutParams.WRAP_CONTENT));}
/*** 適配器刷新子項(xiàng)回調(diào)* @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) {}
}
原因:
????乍一看這段代碼沒有什么問題,但實(shí)際上這里有一個(gè)很大的坑。通過在 afterTextChanged 方法上增加 Log 記錄可以發(fā)現(xiàn),該方法會(huì)被多次的調(diào)用,其根本原因是因?yàn)?EditText 的被重新復(fù)用,并且重新繪制!當(dāng)重繪之后 該回調(diào)函數(shù)沒有獲取到填充的數(shù)據(jù),還是原來復(fù)用的數(shù)據(jù)。
解決辦法:每次填充數(shù)據(jù)之前先移除 TextWatcher 監(jiān)聽器,然后為 EditText 填充數(shù)據(jù) ,最后在為 EditText 添加 TextWatcher 監(jiān)聽器,
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滾動(dòng)后圖片閃爍,圖片切換明顯
場(chǎng)景:
????RecyclerView 的Item布局中都包含ImageView,加載圖片使用Glide加載,當(dāng)ImageView填充圖片之后,滑出屏幕在滑回,回看見圖片回閃一下,或者先顯示上一張圖片瞬間切換到應(yīng)該顯示的圖片,切換明顯
原因:
????因?yàn)镽ecyclerView 的ViewHolder復(fù)用,當(dāng)顯示該圖片時(shí),在RecyclerView 的holder復(fù)用池中取出一個(gè)之前的Holder顯示該圖片,但是此Holder還持有之前的圖片,所以如果該圖片和此Holder持有的圖片相同就閃爍,不同就會(huì)有明顯的切換。
解決方案:
????將數(shù)據(jù)綁定到ViewHolder的Tag,當(dāng)刷新數(shù)據(jù)時(shí),判斷此ViewHolder的Tag的之前綁定的數(shù)據(jù)與當(dāng)前數(shù)據(jù)比較,相同就不刷新數(shù)據(jù),不相同就使用Glide的placeholder墊一個(gè)白色或無色圖
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 滾動(dòng)后數(shù)據(jù)消失
2. RecyclerView中使用EditText
3.小心!Listview結(jié)合EditText使用實(shí)例中遇到的那些坑
總結(jié)
以上是生活随笔為你收集整理的Android踩坑日记:RecyclerView中EditText和ImageView的ViewHolder复用坑的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。