Android開發故障:RecyclerView中EditText和ImageView的ViewHolder復用錯誤解決方案

您所在的位置:网站首页 云仓库收费标准 Android開發故障:RecyclerView中EditText和ImageView的ViewHolder復用錯誤解決方案

Android開發故障:RecyclerView中EditText和ImageView的ViewHolder復用錯誤解決方案

#Android開發故障:RecyclerView中EditText和ImageView的ViewHolder復用錯誤解決方案 | 来源: 网络整理| 查看: 265

RecyclerView中EditText和ImageView的ViewHolder復用坑

RecyclerView作為ListView的升級版,目前來講講開發過程遇到的坑。

RecyclerView 中使用 EditText 滾動後數據消失,錯亂 場景:RecyclerView中的每個Item的ViewHolder佈局中為都有EditText控件,且ViewHolder實現文本改變監聽器TextWatcher,用來在用戶輸入後將數據取出寫入到 列表數據中。 添加文本後,上下滑動RecyclerView且將Item劃出屏幕。如:填寫此EditText為1後,滑出屏幕滑回,文本可能變成0後或其他 結果:對應位置上的EditText未能顯示Adapter數據集中對應位置的Text

/*recyclerview優化的holder*/ public static abstract class BaseViewHolder extends RecyclerView.ViewHolder{ /** * 構造 * * @param itemView 初始化根佈局 */ public BaseViewHolder(View itemView) { super(itemView); /*不設置,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 findViewById(int resId){ return (T) itemView.findViewById(resId); } } /*ViewHolder*/ public class ViewHolderContentText extends RecyclerViewBaseAdapter.BaseViewHolder implements TextWatcher, { 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) { /*將寫入EditText的文本保存到Adapter的DataList中*/ } }

原因: 乍一看這段代碼沒有什麼問題,但實際上這裡有一個很大的坑。通過在 afterTextChanged 方法上增加 Log 記錄可以發現,該方法會被多次的調用,其根本原因是因為 EditText 的被重新復用,並且重新繪制!當重繪之後 該回調函數沒有獲取到填充的數據,還是原來復用的數據。

解決辦法:每次填充數據之前先移除 TextWatcher 監聽器,然後為 EditText 填充數據 ,最後在為 EditText 添加 TextWatcher 監聽器,

/*ViewHolder*/ public class ViewHolderContentText extends RecyclerViewBaseAdapter.BaseViewHolder implements TextWatcher, { 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){ /** * recyclerview中使用editext導致數據混亂情況:必須這樣設置TextWatcher * */ //1,為瞭避免TextWatcher在第2步被調用,提前將他移除 if (contentText.getTag(R.id.tag_textWatcher_data) instanceof TextWatcher){ contentText.removeTextChangedListener(this); } //2,移除TextWatcher之後,設置EditText的Text。 String text=textBean.getContentText(); contentText.setText(text); //3,重新添加 TextWatcher 監聽器 contentText.addTextChangedListener(this); //4,將TextWatcher綁定到EditText 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) { /*將寫入EditText的文本保存到Adapter的DataList中*/ } }

RecyclerView 中使用 ImageView滾動後圖片閃爍,圖片切換明顯。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3