Android开发中ListView与EditText的冲突汇总

在Android开发中,有时候会遇到ListView中嵌套了一些EditText的情况,这个时候很容易发生一些冲突问题,解决方案列举如下。




点击EditText弹出软键盘导致EditText焦点丢失和文本重置问题

问题描述:点击EditText,弹出软键盘,会导致ListView调用getView()重绘,从而导致本来应该在EditText上的焦点被刷新而消失了,从而在软键盘上输入任何文字都没有显示没有效果,必须再点击一次EditText才会有焦点,并且无论输入什么内容隐藏软键盘后再次由于重绘又变回原来的文本内容。


解决方案

定义一个整型变量来标志点击的是哪个EditText:

private int index = -1;


在getView中为EditText添加onTouch事件:

rightEt.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                index = position;
            }
            return false;
        }
});


在getView()的结尾处判断当前绘制的Item的position是不是刚才点击的那个EditText:

rightEt.clearFocus();
if(index != -1 && index == position){
     //强制加上焦点
     rightEt.requestFocus();
     //设置光标显示到编辑框尾部
     rightEt.setSelection(rightEt .getText().length());
     //重置
     index = -1;
}


思路:点击某个Item里的EditText,将该Item的position赋给index,弹出软键盘之后,ListView全部重新绘制,每次调用getView时都进行判断当前绘制的Item是否是点击的那个EditText所在的Item,如果是,则将该EditText对焦,并设置光标显示于文本尾部。


解决了焦点问题,还需要解决EditText文本被重新绘制问题:

为EditText设置OnFocusChangeListener事件:

rightEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(!hasFocus){
            datas.get(position).setStrRightTv(rightEt.getText().toString());
        }
    }
});


思路:一旦失去了焦点,就用此时的EditText上的文本内容去更新数据源。




ListView与EditText多行文本时的滑动冲突问题

问题描述:当EditText嵌套在ListView中且EditText设置是多行文本时,EditText本身内容本应该自带滚动效果,但当点击EditText内部滑动的时候,发现失效,这是由于外层的ListView拦截了它的子控件EditText的事件导致的。

解决方案

mEditText.setOnTouchListener(this);  
  
@Override  
public boolean onTouch(View v, MotionEvent event) {  
    switch (v.getId()) {  
        case R.id.edit_text:  
            v.getParent().requestDisallowInterceptTouchEvent(true);  
            switch (event.getAction()) {  
                case MotionEvent.ACTION_UP:  
                    v.getParent().requestDisallowInterceptTouchEvent(false);  
                    break;  
            }  
    }  
    return false;  
}  



思路:当发生某种触摸事件时,我们可以通过调用父控件的方法requestDisallowInterceptTouchEvent(true)来告诉父控件,我不需要你来处理这个事件,我自己可以处理。

你可能感兴趣的:(Android)