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> * 只有当触摸事件没有被任何的View或ViewGroup处理过的时候,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上的触摸操作生成的触摸事件都首先会触发Activity中dispatchTouchEvent方法的执行,其源码如下所示: * <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返回了false,ViewGroup才会依次遍历其子View, * 其会通过调用isTransformedTouchPointInView方法判断MotionEvent所携带的触摸事件的坐标是否落在子View的范围内, * 如果触摸事件的坐标恰好落在了该子View范围内,说明我们触摸了当前ViewGroup内的该子View, * 这样ViewGroup就会把触摸事件的坐标以及该子View传递给dispatchTransformedTouchEvent方法, * 在该方法内会调用子View的dispatchTouchEvent方法,其返回值表示自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方法中是先执行OnTouchListener的onTouch方法, * 一旦其返回true,就不会调用View自身的onTouchEvent方法了, * 只有OnTouchListener没有处理触摸事件才会在后面执行View的onTouchEvent方法。 * * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { Log.i(TAG, "onTouchEvent: 自定义 View onTouchEvent "); return super.onTouchEvent(event); } /** * dispatchTouchEvent是View处理触摸事件的入口。在该方法中,View首先会查看其有没有设置过OnTouchListener, * 如果设置过就调用OnTouchListener的onTouch方法,如果其返回了true, * 就表明触摸事件被处理了,result就会设置为true。如果触摸事件没有被OnTouchListener处理, * 那么就会执行View的onTouchEvent方法,如果onTouchEvent返回了true,就表示触摸事件被View处理了, * result就被设置为了true。 * * @param event * @return */ @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.i(TAG, "dispatchTouchEvent: 自定义 View dispatchTouchEvent "); return super.dispatchTouchEvent(event); } }
07-18
07-18
07-18
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交