Android Touch事件传递

一、前言
Android的Touch事件属于一个很基本的Android知识点,在面试中经常会被问到,在实际的代码开发中偶然也会碰到,特别是在自定义控件的时候,需要处理自定义控件与底层布局的冲突。因此很有必要总结一下Android Touch事件的传递过程。
二、Android Touch事件的相关介绍
Touch事件的分发,拦截和处理函数
public boolean dispachTouchEvent(MotionEvent ev) 事件的分发函数
public boolean onInterceptTouchEvent(MotionEvent ev)事件的函数
public boolean onTouchEvent(MotionEvent ev) 事件的处理函数
这三个方法在ViewGroup,View,Activity中,具体的情况如下表:
事件函数
ViewGroup
View
Activity
dispachTouchEvent
onInterceptTouchEvent
onTouchEvent
三、事件的处理流程
先上代码,参考代码如下,一个MainActivity.java, 两个自定义控件MyLayoutFirst.java,MyLayoutSecond.java。在MainActivity的布局文件中,MyLayoutSecond处于最上层,MyLayoutSecond包含MyLayoutFirst。
3.1 参考运行代码
1.MainActivity.java
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. activity_main );
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.main, menu);
return true ;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log. i ( "yzy" , "MainActivity->dispatchTouchEvent->" + MyUtils. getActionName (ev));
return super .dispatchTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log. e ( "yzy" , "MainActivity->onTouchEvent->" + MyUtils. getActionName (event));
return super .onTouchEvent(event);
}
}
2.MyLayoutFirst.java
public class MyLayoutFirst extends LinearLayout {
private static final String TAG = "MyLayoutFirst" ;

public MyLayoutFirst(Context context, AttributeSet attrs) {
super (context, attrs);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log. w ( "yzy" , "MyLayoutFirst->onInterceptTouchEvent->" + MyUtils. getActionName (ev));
return super .onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
Log. e ( "yzy" , "MyLayoutFirst->onTouchEvent->" + MyUtils. getActionName (event));
return super .onTouchEvent(event);
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log. i ( "yzy" , "MyLayoutFirst->dispatchTouchEvent->" + MyUtils. getActionName (ev));
return super .dispatchTouchEvent(ev);
}
}
3. MyLayoutSecond.java
public class MyLayoutSecond extends LinearLayout {
private static final String TAG = "MyLayoutSecond" ;
public MyLayoutSecond(Context context, AttributeSet attrs) {
super (context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log. e ( "yzy" , "MyLayoutSecond->MyLayoutSecond->" + MyUtils. getActionName (event));
return super .onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log. w ( "yzy" , "MyLayoutSecond->onInterceptTouchEvent->" + MyUtils. getActionName (ev));
return super .onInterceptTouchEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log. i ( "yzy" , "MyLayoutSecond->dispatchTouchEvent->" + MyUtils. getActionName (ev));
return super .dispatchTouchEvent(ev);
}
}
4.MyUtils.java
public class MyUtils
{
private static final String TAG = "MyUtils" ;
public static String getActionName(MotionEvent event)
{
String name = "" ;
switch (event.getAction())
{
case MotionEvent. ACTION_DOWN :
name = "ACTION_DOWN" ;
break ;
case MotionEvent. ACTION_MOVE :
name = "ACTION_MOVE" ;
break ;
case MotionEvent. ACTION_UP :
name = "ACTION_UP" ;
break ;
}
return name ;
}
}
5.布局XML文件
< RelativeLayout 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" >
< com.example.moxie.testapplication.MyLayoutFirst
android :id= "@+id/layout_first"
android :layout_width= "match_parent"
android :layout_height= "match_parent"
android :background= "#FF0000" >
< com.example.moxie.testapplication.MyLayoutSecond
android :id= "@+id/layout_second"
android :layout_width= "320dip"
android :layout_height= "120dip"
android :layout_gravity= "center"
android :background= "#0000FF" >
</ com.example.moxie.testapplication.MyLayoutSecond >
</ com.example.moxie.testapplication.MyLayoutFirst >
</ RelativeLayout >
3.2 Touch事件流程
经过上面测试代码运行可以总结Touch事件的传递流程如下:


事件处理流程为:Activity--(分发)-->父控件--(分发)-->父控件--(拦截)-->子控件-->(分发)-->子控件-->(拦截)-->子控件-->(处理)-->父控件-->(处理)-->Activity(处理)
1.事件会由底层往上层进行分发和拦截;
2.如果1中没有进行处理,则在上层子空间中执行消耗事件的操作,没有则继续传递到父控件或底层的Activity。
3.如果中途事件被消耗,则不会继续传递。

猜你喜欢

转载自blog.csdn.net/polo2044/article/details/80684513
今日推荐