TouchEvent

package com.example.admin.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


/**
 * http://blog.csdn.net/iispring/article/details/50364126
 *
 * http://blog.csdn.net/yanbober/article/details/45932123
 *
 *
 *
 * 下面 是 触摸事件 流程
 * dispatchTouchEvent: MainActivity 事件分发
 * onUserInteraction: 这个是 干嘛的
 *
 * dispatchTouchEvent: 自定义 ViewGroup dispatchTouchEvent
 * onInterceptTouchEvent: 自定义 ViewGroup onInterceptTouchEvent
 *
 * dispatchTouchEvent: 自定义 View dispatchTouchEvent
 * onTouchEvent: 自定义 View onTouchEvent
 *
 * onTouchEvent: 自定义 ViewGroup onTouchEvent
 * onTouchEvent: MainActivity  onTouchEvent事件
 *
 * dispatchTouchEvent: MainActivity 事件分发
 * onTouchEvent: MainActivity  onTouchEvent事件
 *
 */
public class MainActivity extends AppCompatActivity {


    private static final String TAG = "Z";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i(TAG, "onCreate: MainActivity 创建了");
    }

    /**
     * 事件 分发
     *
     *

     第一条主线是,从Activity -> ViewGroup -> View     从外向内依次调用dispatchTouchEvent方法,android会依次把MotionEvent参数传递给该方法。
     dispatchTouchEvent的作用是传递触摸事件,该主线体现了将触摸事件从外向内逐级传递派发的过程,
     dispatchTouchEvent是每次传递触摸事件的入口。

     第二条主线是,从View -> ViewGroup -> Activity     从内向外依次调用onTouchEvent方法,Android会依次把MotionEvent参数传递给该方法。
     onTouchEvent的作用是处理触摸事件,该主线体现了将触摸事件从内向外逐级处理的过程。

     *
     */


    /**
     * 触摸事件
     * <p>
     * 只有当触摸事件没有被任何的ViewViewGroup处理过的时候,Activity才会执行自己的onTouchEvent去处理触摸事件。
     *
     * @param event 事件
     * @return 消费 不消费
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i(TAG, "onTouchEvent: MainActivity  onTouchEvent事件 ");
        return super.onTouchEvent(event);
    }

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
        Log.i(TAG, "onUserInteraction: 这个是 干嘛的 ");
    }


    /**
     * 派遣 分发 触摸事件
     * <p>
     * 所有在UI上的触摸操作生成的触摸事件都首先会触发ActivitydispatchTouchEvent方法的执行,其源码如下所示:
     * <p>
     * public boolean dispatchTouchEvent(MotionEvent ev) {
     * if (ev.getAction() == MotionEvent.ACTION_DOWN) {
     * onUserInteraction();
     * }
     * if (getWindow().superDispatchTouchEvent(ev)) {
     * return true;
     * }
     * return onTouchEvent(ev);
     * }
     *
     * @param ev
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i(TAG, "dispatchTouchEvent: MainActivity 事件分发 ");
        return super.dispatchTouchEvent(ev);
    }


}



package com.example.admin.myapplication.viewgroup;

import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

/**
 * Created by admin on 2017/9/5.
 * <p>
 * TODO 自定义 线性 布局
 */
public class ZLinearLayout extends LinearLayout {

    private static final String TAG = "Z";

    public ZLinearLayout(Context context) {
        super(context);
    }

    public ZLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ZLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * ViewGroup 触摸事件
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i(TAG, "onTouchEvent: 自定义 ViewGroup onTouchEvent ");
        return super.onTouchEvent(event);
    }

    /**
     * ViewGroup 事件 分发
     * <p>
     * dispatchTouchEvent方法是ViewGroup对触摸事件进行处理的入口。
     * <p>
     * ViewGroup中定义了一个TouchTarget类型的成员变量mFirstTouchTarget,用于保存当前ViewGroup中处理了触摸事件的子View     * <p>
     * <p>
     * 首先,dispatchTouchEvent方法会调用其自身的onInterceptTouchEvent方法,
     * onInterceptTouchEvent是用来拦截ViewGroup将触摸事件传递给其子View的,
     * 如果该方法返回true,就表示ViewGroup应该拦截触摸事件;如果返回false     * 表示ViewGroup不应该拦截触摸事件,应该将触摸事件传递给子View     * dispathTouchEvent方法中还定义了一个boolean类型的handled变量,
     * 用于保存dispathTouchEvent方法的返回值,如果是true就表示触摸事件被当前的ViewGroup处理了,
     * 反之则表示没被处理。
     *
     * @param ev
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i(TAG, "dispatchTouchEvent: 自定义 ViewGroup dispatchTouchEvent ");
        return super.dispatchTouchEvent(ev);
    }

    /**
     * ViewGroup 事件拦截
     * <p>
     * 然后,只有当onInterceptTouchEvent返回了falseViewGroup才会依次遍历其子View     * 其会通过调用isTransformedTouchPointInView方法判断MotionEvent所携带的触摸事件的坐标是否落在子View的范围内,
     * 如果触摸事件的坐标恰好落在了该子View范围内,说明我们触摸了当前ViewGroup内的该子View     * 这样ViewGroup就会把触摸事件的坐标以及该子View传递给dispatchTransformedTouchEvent方法,
     * 在该方法内会调用子ViewdispatchTouchEvent方法,其返回值表示自View是否处理了触摸事件,
     * 如果dispatchTransformedTouchEvent返回true,表示子View处理了触摸事件,
     * 这样ViewGroup会通过调用addTouchTarget方法将mFirstTouchTarget绑定该子View     * 并且变量alreadyDispatchedToNewTouchTarget也会设置为true,表示已经有子View处理了触摸事件。
     * 一旦有子View处理了触摸事件,ViewGroup就会通过break跳出for循环,不再对其他子View进行遍历。
     * <p>
     * 之前提到过onInterceptTouchEvent用于拦截ViewGroup向子View传递触摸事件,
     * ViewGroup中的默认实现一直返回false,即表示不拦截。我们可以重写该方法以实现我们自己的触摸事件拦截逻辑。
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.i(TAG, "onInterceptTouchEvent: 自定义 ViewGroup onInterceptTouchEvent");
        return super.onInterceptTouchEvent(ev);
    }


}


package com.example.admin.myapplication.view;

import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;

/**
 * Created by admin on 2017/9/5.
 * <p>
 * TODO  自定义 TextView
 */
public class ZTextView extends TextView {

    public ZTextView(Context context) {
        super(context);
    }

    public ZTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ZTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private static final String TAG = "Z";

    /**
     * 由上可以看出,在dispatchTouchEvent方法中是先执行OnTouchListeneronTouch方法,
     * 一旦其返回true,就不会调用View自身的onTouchEvent方法了,
     * 只有OnTouchListener没有处理触摸事件才会在后面执行ViewonTouchEvent方法。
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i(TAG, "onTouchEvent: 自定义 View onTouchEvent ");
        return super.onTouchEvent(event);
    }

    /**
     * dispatchTouchEventView处理触摸事件的入口。在该方法中,View首先会查看其有没有设置过OnTouchListener     * 如果设置过就调用OnTouchListeneronTouch方法,如果其返回了true     * 就表明触摸事件被处理了,result就会设置为true。如果触摸事件没有被OnTouchListener处理,
     * 那么就会执行ViewonTouchEvent方法,如果onTouchEvent返回了true,就表示触摸事件被View处理了,
     * result就被设置为了true     *
     * @param event
     * @return
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.i(TAG, "dispatchTouchEvent: 自定义 View dispatchTouchEvent ");
        return super.dispatchTouchEvent(event);
    }

}


 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值