您的位置:首页 > 其它

自定义ViewGroup(二)

2017-11-15 14:00 267 查看

事件分发

自定义ViewGroup这块,不可能一直都是在测量和布置位置,那这样的布局没什么用,还得涉及到事件分发与拦截,哪些归父处理,哪些归子处理。

始终跟着大神走,还是看鸿洋大神的博客:Android ViewGroup事件分发机制

先自定义一个按钮:

public class MyButton extends AppCompatButton {

public static final String TAG = MyButton.class.getSimpleName();

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

/**
* 触摸事件
*
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "onTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "onTouchEvent ACTION_UP");
break;
default:
break;
}
return super.onTouchEvent(event);
}

/**
* 分发事件
*
* @param event
* @return
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG,
4000
"dispatchTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "dispatchTouchEvent ACTION_UP");
break;
default:
break;
}
return super.dispatchTouchEvent(event);
}
}


然后自定义一个LinearLayout:

public class MyLinearLayout extends LinearLayout {
public static final String TAG = MyLinearLayout.class.getSimpleName();

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

/**
* 分发
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "dispatchTouchEvent ACTION_UP");
break;

default:
break;
}
return super.dispatchTouchEvent(ev);
}

/**
* 触摸
*/
@Override
public boolean onTouchEvent(MotionEvent event) {

int action = event.getAction();

switch (action) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "onTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "onTouchEvent ACTION_UP");
break;

default:
break;
}

return super.onTouchEvent(event);
}

/**
* 拦截
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onInterceptTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "onInterceptTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "onInterceptTouchEvent ACTION_UP");
break;

default:
break;
}

return super.onInterceptTouchEvent(ev);
}

@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
Log.e(TAG, "requestDisallowInterceptTouchEvent");
super.requestDisallowInterceptTouchEvent(disallowIntercept);
}


然后在布局中引用:

<?xml version="1.0" encoding="utf-8"?>
<com.xiey94.view.viewgroup.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<com.xiey94.view.view.MyButton
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="clcik"
android:textAllCaps="false" />

</com.xiey94.view.viewgroup.MyLinearLayout>


调用:

public class MainActivity extends AppCompatActivity {
protected static final String TAG = "MyButton";
private MyButton btn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (MyButton) findViewById(R.id.btn);
btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onTouch ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "onTouch ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "onTouch ACTION_UP");
break;
default:
break;
}
return false;
}
});
}
}


触碰并移动后的打印如下:

11-15 05:32:35.202 1584-1584/com.xiey94.view E/MyLinearLayout: dispatchTouchEvent ACTION_DOWN
11-15 05:32:35.202 1584-1584/com.xiey94.view E/MyLinearLayout: onInterceptTouchEvent ACTION_DOWN
11-15 05:32:35.202 1584-1584/com.xiey94.view E/MyButton: dispatchTouchEvent ACTION_DOWN
11-15 05:32:35.202 1584-1584/com.xiey94.view E/MyButton: onTouch ACTION_DOWN
11-15 05:32:35.202 1584-1584/com.xiey94.view E/MyButton: onTouchEvent ACTION_DOWN
11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyLinearLayout: dispatchTouchEvent ACTION_MOVE
11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyLinearLayout: onInterceptTouchEvent ACTION_MOVE
11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyButton: dispatchTouchEvent ACTION_MOVE
11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyButton: onTouch ACTION_MOVE
11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyButton: onTouchEvent ACTION_MOVE
11-15 05:32:35.426 1584-1584/com.xiey94.view E/MyLinearLayout: dispatchTouchEvent ACTION_UP
11-15 05:32:35.426 1584-1584/com.xiey94.view E/MyLinearLayout: onInterceptTouchEvent ACTION_UP
11-15 05:32:35.426 1584-1584/com.xiey94.view E/MyButton: dispatchTouchEvent ACTION_UP
11-15 05:32:35.426 1584-1584/com.xiey94.view E/MyButton: onTouch ACTION_UP
11-15 05:32:35.426 158
b289
4-1584/com.xiey94.view E/MyButton: onTouchEvent ACTION_UP


可以看出他们的调用顺序:

ViewGroup –>View

先调用ViewGroup的事件分发dispatchTouchEvent,然后拦截onInterceptTouchEvent,传到子View*(这里并没有拦截),View分发dispatchTouchEvent,然后View的onTouch,最后是View的onTouchEvent

从这里可以看出,ViewGroup要比View多一个onInterceptTouchEvent,这也是它独有的特性;

这里并不解析源码,只是初步的了解一下它的分发机制,参考 一个Android群英传里的



1、ViewGroup拦截:1 –>6

2、ViewGroup不拦截,MyButton拦截并处理:1–>2–>3

3、ViewGroup不拦截,MyButton不拦截不处理:1–>2–>4

大的流程大概就是这样,至于源码的分析这种活,现在干不了,循序渐进吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: