android事件传递

1、事件(MotionEvent)

事件被ViewGroup拦截或者子View的onTouchEvent都返回false,事件由ViewGroup处理
子View的onTouchEvent都返回false,则父View的onTouchEvent被调用,都不处理则由Activity的onTouchEvent处理

先传递ACTION_DOWN 如果处理,再传递ACTION_MOVE和ACTION_MOVE

 ACTION_CANCEL //取消事件   由程序产生


OnTouch时 GroupView调用顺序:
    dispatchTouchEvent       //事件分发      返回true处理结束,返false不处理  没必要重写
    onInterceptTouchEvent  //事件的拦截  默认返false
    onTouchEvent                 //事件处理      子向父传 View中默认返true,既处理事件
onInterceptTouchEvent和onTouchEvent决定事件的传递方向


底层View一般是一个ViewGroup 默认不拦截点击事件
onInterceptTouchEvent(ViewGroup才有) 
返回true ViewGroup处理事件
如果 onTouchListener 被设置调用onTouch(滑动)
否自 onTouchEvent 被调用
二者都提供 onTouch(优先级高)会屏蔽onTouchEvent
onClick基于onTouchEvent实现,在onTouchEvent中如果设置OnClickListener 则调用onClick
返回false 不拦截
传给子View -> 子View(如果是ViewGroup)的 dispatchTouchEvent
View对事件处理
设了OnTouchListener 调用onTouch
否则调onTouchEventonClick在其中通过performClick触发


当前界面底层容器 DecorView,既setContentView设置的View的父容器,activity.getWindow.getDecorView()可获取
DecorView 继承自FrameLayout 是根View的最底层

getScrollY //View实际位置 正上 负下

event.getY //屏幕上的位置

2、示例

这是一个ScrollView嵌套使用的例子,参考自http://blog.sina.com.cn/s/blog_6271df6f0101ap4w.html

         


MainActivity.java

public class MainActivity extends Activity {
	ScrollView scrollView;//外层ScrollView
    InnerScrollView innerScrollView;//内从ScrollView
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        scrollView = (ScrollView)findViewById(R.id.scrollView1);
        innerScrollView = (InnerScrollView)findViewById(R.id.scrollView2);
        //内层的ScrollView需要向外层的ScrollView传递滑动事件
        innerScrollView.parentScrollView = scrollView;
    }
}


InnerScrollView.java

public class InnerScrollView extends ScrollView {
    /**外层ScrollView*/
    public ScrollView parentScrollView;
    /**当前屏幕Y轴上的位置*/
    int currentY;
    public InnerScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (parentScrollView == null) {
            return super.onInterceptTouchEvent(ev);
        } else {
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                currentY = (int)ev.getY();
                //requestDisallowInterceptTouchEvent 是ViewGroup类中的一个公用方法,子类可通过此方法告诉父类是否拦截点击事件
                requestDisallowInterceptTouchEvent(true);//此处不做拦截会影响灵敏度
                return super.onInterceptTouchEvent(ev);
            } else if (ev.getAction() == MotionEvent.ACTION_UP) {
                parentScrollView.requestDisallowInterceptTouchEvent(false);//此处不回复拦截会影响灵敏度
            } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
            }
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        View child = getChildAt(0);
        if (parentScrollView != null) {
            if (ev.getAction() == MotionEvent.ACTION_MOVE) {
                int height = child.getMeasuredHeight();//获取InnerScrollView中嵌套的线性布局的高度
                int self_height = getMeasuredHeight();//获取InnerScrollView自身的高度
                height = height - self_height;
                int scrollY = getScrollY();
                int y = (int)ev.getY();
                if (currentY < y) { // 手指向下滑动
                    if (scrollY <= 0) {
                        // 如果向下滑动到头,就把滚动交给父Scrollview	onTouchEvent要返回false
                        parentScrollView.requestDisallowInterceptTouchEvent(false);
                        return false;
                    } else {
                        parentScrollView.requestDisallowInterceptTouchEvent(true);
                    }
                } else if (currentY > y) {
                    if (scrollY >= height) {
                        // 如果向上滑动到头,就把滚动交给父Scrollview
                        parentScrollView.requestDisallowInterceptTouchEvent(false);
                        return false;
                    } else {
                        parentScrollView.requestDisallowInterceptTouchEvent(true);
                    }
                }
                currentY = y;
            }
        }
        return super.onTouchEvent(ev);
    }
}

参考代码: http://download.csdn.net/detail/duduhali/9425834

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值