ListView+EditText使用遇到的坑
最近项目中某功能需要ListView嵌套EditText来实现,使用过程中遇到一些问题:
1、点击弹出编辑框,edittext会失去焦点。
解决焦点丢失的问题
解决思路:软键盘弹出的时候会重新绘制界面,因此ListView进行了一次重新绘制,重新走了一边getView方法,生成了一个新的EditText,而之前展示光标的EditText被销毁,所以才造成了EditText的焦点丢失。既然焦点丢失是因为ListView的重绘导致的,那我们就可以定义一个变量mTouchItemPosition来记录用户触碰的EditText的位置,然后在getView方法中去判断当前的position是否和用户触碰的位置相等,如果相等则让其获得焦点,否则清除焦点。而mTouchItemPosition的值可以在EditText的OnTouch事件中获取。
mTouchItemPosition = -1;
holder.et_buyer_words.setTag(position);
if (mTouchItemPosition == position) { holder.et_buyer_words.requestFocus(); holder.et_buyer_words.setSelection(holder.et_buyer_words.getText().length()); } else { holder.et_buyer_words.clearFocus(); }
holder.et_buyer_words.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { //注意,此处必须使用getTag的方式,不能将position定义为final mTouchItemPosition = (Integer) view.getTag(); return false; } });
2、输入内容后,向下滑动因为listview的item重用机制,在上面输入的内容下面的item也会显示;向下滑动再拉回来原来的数据消失。
添加保存数据的功能
首先需要拿到EditText变化之后的数据,然后将这些数据替换掉之前的就可以了。
由于TextWatcher的afterTextChanged方法中获取不到当前position,所以我们需要新建一个内部类MyTextWatcher实现TextWatcher接口并持有一个position,其次在ViewHolder中需要持有一个MyTextWatcher的引用来动态更新其position的值,以下为完整代码:
1 //留言 listview+edittext完美解决 2 mTouchItemPosition = -1; 3 holder.updateCartBean(cartBean); 4 holder.et_buyer_words.setText(cartBean.getMemo()); 5 holder.et_buyer_words.setTag(position); 6 holder.et_buyer_words.addTextChangedListener(holder.mTextWatcher); 7 if (mTouchItemPosition == position) { 8 holder.et_buyer_words.requestFocus(); 9 holder.et_buyer_words.setSelection(holder.et_buyer_words.getText().length()); 10 } else { 11 holder.et_buyer_words.clearFocus(); 12 } 13 holder.et_buyer_words.setOnTouchListener(new View.OnTouchListener() { 14 15 @Override 16 public boolean onTouch(View view, MotionEvent event) { 17 //注意,此处必须使用getTag的方式,不能将position定义为final 18 mTouchItemPosition = (Integer) view.getTag(); 19 return false; 20 } 21 });
1 class ViewHolder{ 2 MyTextWatcher mTextWatcher; 3 4 public void updateCartBean(ShoppingCartListBean cartListBean) { 5 mTextWatcher.setCartBean(cartListBean); 6 } 7 } 8 9 class MyTextWatcher implements TextWatcher { 10 private ShoppingCartListBean cartBean; 11 12 public void setCartBean(ShoppingCartListBean cartBean) { 13 this.cartBean = cartBean; 14 } 15 16 @Override 17 public void onTextChanged(CharSequence s, int start, int before, int count) { 18 19 } 20 21 @Override 22 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 23 24 } 25 26 @Override 27 public void afterTextChanged(Editable s) { 28 cartBean.setMemo(s.toString()); 29 } 30 }
总结:ListView嵌套过程中,因为复用机制还是会出很多问题的。查资料说RecycleView可以解决EditText焦点错乱问题,但基于项目整个架子都是ListView为底,没办法替换。所以以上是我的解决办法啦。
By LiYing