例如在第三個 item 將 checkbox 勾選,然後將儲存在 Adapter 中的 data set 更新,更新後的第三個 item checkbox 預設是沒勾選的狀態,則在呼叫 notifyDataSetChanged 時就會 call 到 第三個 item checkbox 的 onCheckedChange
調查後發現,我使用 setViewBinder 來初始化 checkbox 的勾選狀態,但是在 setChecked 之前先用 setOnCheckedChangeListener 設定了
@Override public boolean setViewValue(View view, Object o, String s) { // Not correct!! AppCompatCheckBox cb = (AppCompatCheckBox)view; cb.setOnCheckedChangeListener(listener); cb.setChecked((boolean)o); // Correct cb.setOnCheckedChangeListener(null); AppCompatCheckBox cb = (AppCompatCheckBox)view; cb.setChecked((boolean)o); cb.setOnCheckedChangeListener(listener); }
notifyDataSetChanged API 的行為應該會保存 item 之前的資料,只對需要的部分作改變,所以第三個 item checkbox 狀態會從 check 到 uncheck,如果有註冊了 listener,則理應通知 listener
那解法就是在初始化 checkbox 時,先 remove 掉 listener 在設定 checkbox,然後才註冊 listener,這樣就避免了不必要的 onCheckedChange 呼叫
此外,還有一個額外需要注意的點是,之前提過,用 notifyDataSetChanged 來更新 ListView,ListView item 之前的狀態都會被保存,所以原本被勾選的 item 更新後沒有被勾選的話會有 checkbox 被取消的動畫效果
如果不想要這個效果的話,則不應該用 notifyDataSetChanged,可以改用 setAdapter 重新設定 adapter 給 ListView,這樣 ListView 就會將整個內容銷毀再更新,就不會有 checkbox 效果,當然這樣會有效能流失,可以感覺到 GUI 的更新速度稍微慢了一點
沒有留言:
張貼留言