滑动冲突小记

这几天工作中遇到不少滑动冲突问题,记录下来,分享一下。
主要有两种情况:

1.ScrollView嵌套ListView

这种情况的应用场景不多,一般应用的话也多用于展示,重新计算下ListView的高度就ok

先上图:
这里写图片描述

顶层布局是一个ScrollView,里面包含一个Edittext,一个Listview,一个Button

正常情况下ScrollView不会拦截掉ListView的点击事件,不过当Edittext中的内容比较多,直到屏幕展示不开出现滚动条时,ScrollView就会拦截掉ListView的点击事件,使Listview没办法正常工作

这里写图片描述
这种情况下Listview的滑动事件会被拦截掉
解决方案:判断点击位置,按位置来确定谁来执行点击事件

解决滑动冲突问题一般有两种解决方式:
外部拦截法和内部拦截法

先来看外部拦截法
外部拦截也就是说从父控件中处理是否拦截点击事件
上代码

//非完整代码
public class MyScrollView extends ScrollView {

    private ListView mListView;
    private float mLeft;
    private float mRight;
    private float mTop;
    private float mBpttom;
    private float mRawX;
    private float mRawY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                int[] location = new int[2];
                mListView.getLocationInWindow(location);
                mLeft = location[0];
                mTop = location[1];
                mRight = mLeft + getWidth();
                mBpttom = mTop + getHeight();
                mRawX = ev.getRawX();
                mRawY = ev.getRawY();
                if(mRawX>mLeft && mRawX<mRight 
                && mRawY>mTop && mRawY<mBpttom){
                    return false;
                }
                return true;
            case MotionEvent.ACTION_MOVE:

                break;
            case MotionEvent.ACTION_UP:

                break;
        }

        return super.onInterceptTouchEvent(ev);
    }
  }

简单说一下,获取Listview在屏幕中的位置,判断点击的坐标是否在Listview中,如果是就直接不去拦截点击事件,让Listview处理

内部拦截法:
在内部view中通过requestDisallowInterceptTouchEvent()方法来干涉父控件是否拦截点击事件

代码逻辑一样的就不上代码了,重写Listview的onTouchEvent方法
如果点击位置在Listview内就调用requestDisallowInterceptTouchEvent(true)

2.ScrollView嵌套可以横向滑动的Webview(和Viewpager嵌套Listview)一样的

这个就比较简单了,判断滑动房间,外部拦截就重写父空间的onIntercepterTouchEvent 内部拦截就重写view空间的onTouchEvent方法,直接上代码

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                mRawX = ev.getRawX();
                mRawY = ev.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                float moveX = ev.getRawX();
                float moveY = ev.getRawY();
                float differX = Math.abs(moveX - mRawX);
                float differY = Math.abs(moveY - mRawY);
                if(differX>differY){
                    return false;
                }else
                    return true;
            case MotionEvent.ACTION_UP:

                break;
        }

        return super.onInterceptTouchEvent(ev);
    }

计算移动距离的绝对值,判断在哪个方向上移动距离长,然后处理事件

顺便提一下,Webview的loadData方法,系统提供的方法有时候也会出现乱码,可以这么处理

mWebView.getSettings().setDefaultTextEncodingName("UTF-8");
mWebView.loadData(mHtmlStr, "text/html; charset=UTF-8", null);

距离上次写博客过去有两个多月了,从10月份来到北京,入职到人生第一家公司,到现在独立开发上线项目第一版,确实太忙了。上线第一版,终于有了些时间,以后争取每周一篇,记录平时项目中的问题和自己在思考的问题,本人水平有限,如果有什么问题,欢迎指正。

邮箱:qiuzhenhuan.hi@gmail.com

欢迎交流。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值