ListView,ScrollView嵌套滑动冲突问题,子view包含EditText等

之前写过ListView和ScrollView嵌套滑动冲突问题,最近刚好遇到ListView的子View包含可以获取焦点的情况,这种情况下只是单纯的给ListView设置onTouchListener会经常失效,也就是滑动冲突重新出现了。

经过同事提点,我自己也测试了一下,解决滑动冲突的成功率果然提高了很多,话不多说,赶紧分享一下。
最开始解决冲突的方式:

listView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //关键是这一句
                scrollView.requestDisallowInterceptTouchEvent(true);
                return false;
            }
        });

这是最简单的,要做ListView和ScrollView滑动能力自动切换可以看一下我之前的一篇分享。下面直接说这次的重点,ListView的ItemView里包含了Button,CheckBox,EditText(尤其是这个)等会获取焦点的控件,解决冲突的方式其实和之前的差不多,我们在自定义的adapter里增加onTouchListener的对象,在构造函数或者另外提供一个set方法,将用于解决冲突的onTouchListener传进ItemView里。

下面是代码
 

TestAdapter testAdapter = new TestAdapter(this, Arrays.asList(testArray), new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //判断是否为滑动,是滑动则让scrollView不可滑动
                //这里只判断了滑动,可根据需要判断主要滑动方向(要用到ACTION_DOWN 和ACTION_UP),
                //我这对解决冲突的精度没有特别高要求,就单纯判断滑动就完事了
                if(event.getAction() == MotionEvent.ACTION_MOVE){
                    scrollView.requestDisallowInterceptTouchEvent(true);
                }
                return false;
            }
        });

然后在会获取焦点的控件里,给它设置传进去的onTouchListener

@Override
    public View getView(int position, View convertView, ViewGroup parentView){
        ViewHolder holder;
        if(convertView == null){
            convertView = View.inflate(mContext, R.layout.test_item, null);
            holder = new ViewHolder();
            holder.tvLabel = (TextView) convertView.findViewById(R.id.tvLabel);
            holder.etValue = (EditText) convertView.findViewById(R.id.etValue);
            //这个控件会获得焦点,直接给它设置onTouchListener
            holder.etValue.setOnTouchListener(onTouchListener);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tvLabel.setText(dataList.get(position));
        holder.etValue.setText(dataList.get(position));
        return convertView;
    }

冲突问题到这就基本解决了。
其实最开始我还尝试使用过

android:descendantFocusability="blocksDescendants"

但是基本上没效果。最后才用这么麻烦的方法。注意这个方法里没有对ListView包含EditText会导致的数据紊乱,光标异常这些问题进行处理,所以说如果用到TextWatcher这些还是需要自己再处理一下的,记录好位置就好了,有空也分享一下这个,但这个网上也有很多,找一下就好了。

发布了24 篇原创文章 · 获赞 2 · 访问量 3670

猜你喜欢

转载自blog.csdn.net/ALee_130158/article/details/95058969