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

    此处判断同上,用两个方法结合时为了增长用户体验,在最后一行时能够经过回车来保存,在其余行时回车可以自动定位到下一个输入框

相关文章
相关标签/搜索