ListView,GridView,RecyclerView滑動錯位的終極解決辦法
阿新 • • 發佈:2019-02-11
直接講重點!
假如你的item佈局裡面包含但不限於這些東西:textView,ImageView,CheckBox,Button...
你一定遇到過滑動列表時item裡面的控制元件錯位,該出現的地方不出現,不該出現的地方反而蹦出來的情況。
我也在網上看過很多解決辦法,很多說給什麼控制元件設定一個tag呀之類的,看著我都覺得麻煩,其實解決滑動錯位並不需要設定什麼tag,就一個if-else就能解決。
下面正片!
問題的所在就是你的adapter裡面,這裡我們直接看一個最簡單ListView 的Adapter,其他的GridView,RecyclerView原理也是一模一樣,就不多贅述。
直接看adapter裡面的getView方法:
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = null; if (convertView == null) { convertView = inflater.inflate(R.layout.item_layout, parent, false); viewHolder = new ViewHolder(); viewHolder.title = (TextView) convertView.findViewById(R.id.title); viewHolder.image = (ImageView) convertView.findViewById(R.id.image); viewHolder.check = (CheckBox) convertView.findViewById(R.id.check); viewHolder.button = (Button) convertView.findViewById(R.id.button); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } ListViewBean listViewBean = mList.get(position); viewHolder.title.setText(listViewBean.getTitle()); //繫結資料 //重點!!! //滑動導致item裡面的控制元件錯位 //第一種情況 // 資料繫結之後滑動錯位 //很多情況我們會寫如下程式碼 //根據image的路徑是否為空來給ImageView賦值 //你可能認為邏輯沒錯,如果iamgePath有路徑那麼才給圖片賦值 //但是執行之後,全TM亂了 if (!"".equals(listViewBean.getImagePath())) { viewHolder.image.setImageURI(Uri.parse(listViewBean.getImagePath())); } //解決方案:只需要再加上一個else就夠了 //為什麼加上一個else就不會錯位了? //我也懶得給你們講快取什麼的(我也不會講) //通俗易懂的來說: // 當進入listViewBean.getImagePath()有路徑的時候, // 程式進了if裡面,裡面明確規定了我要把路徑賦值給imageView,程式就照著我規定的做 // 但是,如果listViewBean.getImagePath()是空的時候,程式不會進入if, // 不僅沒進if,而且你也沒在任何地方給他規定路徑是空的時候他應該做什麼 // 那他就只能胡亂給你填資料咯 if (!"".equals(listViewBean.getImagePath())) { viewHolder.image.setImageURI(Uri.parse(listViewBean.getImagePath())); } else { //所以當路徑為空時,也必須規定該控制元件應該怎麼做 viewHolder.image.setImageResource(R.mipmap.ic_launcher); } // 第二種情況: //設定某一控制元件顯示或者隱藏 //下面的程式碼,我定義了一個boolean型別的屬性,用來判斷我的checkBox是否顯示 //單當你執行之後就會發現,checkBox錯位了 if (listViewBean.isDisPlayCheck()) { viewHolder.check.setVisibility(View.VISIBLE); } //解決方案:同樣也只需要加上一個else //程式碼修改如下,button也同樣 if (listViewBean.isDisPlayCheck()) { viewHolder.check.setVisibility(View.VISIBLE); } else { viewHolder.check.setVisibility(View.GONE); } if (listViewBean.isDisPlayButton()) { viewHolder.button.setVisibility(View.VISIBLE); } else { viewHolder.button.setVisibility(View.GONE); } return convertView; }
總結:只要是在ViewHolder裡面聲明瞭的控制元件,要麼不賦值,要麼在所有分支都賦值,有if,就一定要有else,要讓控制元件無論進入哪一個分支都明白自己應該做什麼事