Android 有關在ListView RecycleView 中使用EditText Checkbox的坑

 

  這是一篇文字超多的博客,哈哈哈,廢話自行過濾···ide

  • 遇到問題

  在開發中咱們常會在ListView , RecycleView 列表中添加EditText輸入框,或者checkbox複選框。post

   

 

   複選框應該是用的比較多的,輸入框淘寶採用的是彈出框的方式,可能在一些特定的狀況下,咱們但願可以直接在列表中輸入,可能會更方便些。spa

  今天說的就是兩個事件code

  CompoundButton.OnCheckedChangeListener

     cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { } });

 

  TextChangedListener

        et.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { } });

 

咱們可能會在Adapter中使用這兩個方法來監聽選擇Checkbox 和 EditText 的變化。blog

那麼咱們遇到的坑是?

   CheckBox事件

  假設咱們我有一個全選按鈕,理想效果是:列表所有選中,全選複選框也選中,若是取消其中一個全選複選框就不選中,若是選中全選,列表全選,若是取消全選,列表取消選中。若是列表所有選中,取消其中一個,而後就會設置全選爲 不選中,那麼就會觸發全選複選框的checkedchange事件,若是全選從選中變爲 未選中,列表所有設置未選中。資源

說了這麼多,挺複雜的,略過···開發

而後你覺得只是列表中的複選框和全選複選框的衝突···你就錯了···實際上不僅如此get

總之,解決複選框的問題很簡單,咱們不用checkedchange事件,由於這個事件不只在用戶操做是觸發,其餘代碼中的設置也會觸發。直接使用 onclick 點擊事件來控制checkbox 的選中和未選,必定要把選中未選的狀態加到 數據列表中。解決以Myviewholder影響的選中錯亂。博客

 

   EditText

   這個就厲害了,我竟不知道該用什麼事件來代替  TextChangedListener ,因爲viewholder減小了view的加載資源耗損,也就是意味着列表中的兩個不是一次加載出來的條目可能使用的是同一個viewholder。

我試過用 焦點離開來作,這個在adapter刷新時仍是有一些問題。

爲何 onclick 事件不會有問題?由於 onclick必定是用戶觸發的,而 TextChanged、onfocus都有多是adapter刷新獲取其餘緣由形成你並不想觸發這個這個事件,沒辦法區分開是用戶輸入的仍是程序形成的。

 

其實原本不想寫博客的,checkbox其實入坑不是第一次了,好久沒開發Android,我又入坑了。主要是 EditText 的問題。好吧我看過其餘解決方式是將 TextWatcher 事件像 viewholder 同樣儲存起來,但我也並無解決問題。

辦法確定是有的,好比和淘寶同樣彈出輸入框輸入,或者當用戶準備輸入的時候右邊顯示一個小圖標點擊一下用來保存,有點像Web上面的,能想象是什麼樣子嗎,哈哈哈。

 

  • 解決方法

  總之我以爲就是找一個能不被其餘代碼影響的事件來代替 TextChanged 以及 CheckedChange 事件。 好比 onclick ,其實我以爲 EditText 在 onfocus 事件上稍加處理可能能夠,由於onfocus 的影響主要是在 Adapter 刷新的時候會改變,以及用戶操做時會改變。  

 

因此,個人終極解決方案:(忽略這個醜界面)

    myViewHolder.et.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean b) { if (!b&&data.size()>position&&!myViewHolder.et.getText().toString().equals(data.get(position).getCheckValue()+"")) { saveCheckValue(myViewHolder, position);//此方式實現將輸入框數據填充到 data 數據集合中,無其餘操做 即 data.get(position).setCheckValue(myViewHolder.et.getText().toString());
 } } }); myViewHolder.et.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View view, int i, KeyEvent keyEvent) { if (data.size()>position&&!myViewHolder.et.getText().toString().equals(data.get(position).getCheckValue()+"")) { if (i == KeyEvent.KEYCODE_ENTER && keyEvent.getAction() == KeyEvent.ACTION_UP) { saveCheckValue(myViewHolder, position); } } return  false;//返回 false 讓此方法可進行其餘操做,如,把光標切換到下一個輸入框
 } });

 

  同時使用了onFocus 事件和 OnKey KEYCODE_ENTER回車事件來獲取輸入框中的值。

  onFocus:

     ①focus 有兩種一種時獲取焦點一種是失去焦點,咱們取失去焦點。因此判斷 !b

    ②因爲操做中有新增一行,刪除一行,當刪除光標所在的行也會引起焦點失去的事件,此時postion的條目可能已經移出,因此判斷 data.size()>position

    🌂爲了不一些沒必要要的賦值操做,因此判斷 當前data 數據集合中的值是否和當前輸入框中的值是否一致,一致就不能夠沒必要再執行賦值操做。因此判斷 !myViewHolder.et.getText().toString().equals(data.get(position).getCheckValue()+"")

  onKey KEYCODE_ENTER

    此處判斷同上,用兩個方法結合時爲了增長用戶體驗,在最後一行時能夠經過回車來保存,在其餘行時回車可以自動定位到下一個輸入框

相關文章
相關標籤/搜索