@ZeroGeek
2016-09-22T11:54:53.000000Z
字数 4834
阅读 822
android
View可以监听交互事件(触碰,点击等),当View与ViewGroup之间重叠时,Android系统是怎么处理这些事件的呢?本文主要分析ACTION_DOWN事件(常用的有ACTION_UP,ACTION_MOVE等)在View之间的传递,涉及下面3个方法:
(代码附录在最后,迫不及待来分析吧)自定义了个LogButton,作为View这类。LogLinearLayout,作为ViewGroup这类,加上Activity,全部重写dispatchTouchEvent,onTouchEvent,onInterceptTouchEvent,并捕获ACTION_DOWN和ACTION_UP事件,输出log。布局就是把一个LogButton放入一个LogLinearLayout中。然后在Activity中监听onTouch事件。
首先自定义个LogButton,作为View这类
public class LogButton extends Button {private static final String TAG = "LogButton";public LogButton(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:Log.d(MainActivity.MY_TAG, TAG+" onTouchEvent :ACTION_DOWN");break;case MotionEvent.ACTION_UP:Log.d(MainActivity.MY_TAG, TAG+" onTouchEvent :ACTION_UP");break;}// 注意这里默认是true。return true;}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:Log.d(MainActivity.MY_TAG, TAG+" dispatchTouchEvent :ACTION_DOWN");break;case MotionEvent.ACTION_UP:Log.d(MainActivity.MY_TAG, TAG+" dispatchTouchEvent :ACTION_UP");break;}return super.dispatchTouchEvent(ev);}}
然后定义个LogLinearLayout,作为ViewGroup这类
public class LogLinearLayout extends LinearLayout {private static final String TAG = "LogLinearLayout";public LogLinearLayout(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:Log.d(MainActivity.MY_TAG, TAG+" onTouchEvent :ACTION_DOWN");break;case MotionEvent.ACTION_UP:Log.d(MainActivity.MY_TAG, TAG+" onTouchEvent :ACTION_UP");break;}// 这里默认是super.onTouchEvent(event)return super.onTouchEvent(event);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:Log.d(MainActivity.MY_TAG, TAG+" onInterceptTouchEvent :ACTION_DOWN");break;case MotionEvent.ACTION_UP:Log.d(MainActivity.MY_TAG, TAG+" onInterceptTouchEvent :ACTION_UP");break;}return super.onInterceptTouchEvent(ev);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:Log.d(MainActivity.MY_TAG, TAG+" dispatchTouchEvent :ACTION_DOWN");break;case MotionEvent.ACTION_UP:Log.d(MainActivity.MY_TAG, TAG+" dispatchTouchEvent :ACTION_UP");break;}return super.dispatchTouchEvent(ev);}}
主界面,其实是Activity类实现了Window的一个Callback接口,里面包含这2个方法。
public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";public static final String MY_TAG = "zero";private LogButton btn;private LogLinearLayout ly;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn = (LogButton) findViewById(R.id.log_btn);ly = (LogLinearLayout) findViewById(R.id.log_ly);btn.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {switch (motionEvent.getAction()) {case MotionEvent.ACTION_DOWN:Log.d(MainActivity.MY_TAG, TAG+" btn onTouch :ACTION_DOWN");break;case MotionEvent.ACTION_UP:Log.d(MainActivity.MY_TAG, TAG+" btn onTouch :ACTION_UP");break;}return false;}});ly.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {switch (motionEvent.getAction()) {case MotionEvent.ACTION_DOWN:Log.d(MainActivity.MY_TAG, TAG+" layout onTouch :ACTION_DOWN");break;case MotionEvent.ACTION_UP:Log.d(MainActivity.MY_TAG, TAG+" layout onTouch :ACTION_UP");break;}return false;}});}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:Log.d(MainActivity.MY_TAG, TAG+" dispatchTouchEvent :ACTION_DOWN");break;case MotionEvent.ACTION_UP:Log.d(MainActivity.MY_TAG, TAG+" dispatchTouchEvent :ACTION_UP");break;}return super.dispatchTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:Log.d(MainActivity.MY_TAG, TAG+" onTouchEvent :ACTION_DOWN");break;case MotionEvent.ACTION_UP:Log.d(MainActivity.MY_TAG, TAG+" onTouchEvent :ACTION_UP");break;}return super.onTouchEvent(event);}}
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.zero.eventdemo.MainActivity"><com.zero.eventdemo.LogLinearLayoutandroid:id="@+id/log_ly"android:layout_width="match_parent"android:layout_height="wrap_content"><com.zero.eventdemo.LogButtonandroid:id="@+id/log_btn"android:layout_width="200dp"android:layout_height="wrap_content"android:text="log button"/></com.zero.eventdemo.LogLinearLayout></LinearLayout>