自定义ViewGroup(二)

来源:互联网 发布:淘宝花种子哪家好 编辑:程序博客网 时间:2024/06/08 11:38

事件分发

自定义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, "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_DOWN11-15 05:32:35.202 1584-1584/com.xiey94.view E/MyLinearLayout: onInterceptTouchEvent ACTION_DOWN11-15 05:32:35.202 1584-1584/com.xiey94.view E/MyButton: dispatchTouchEvent ACTION_DOWN11-15 05:32:35.202 1584-1584/com.xiey94.view E/MyButton: onTouch ACTION_DOWN11-15 05:32:35.202 1584-1584/com.xiey94.view E/MyButton: onTouchEvent ACTION_DOWN11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyLinearLayout: dispatchTouchEvent ACTION_MOVE11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyLinearLayout: onInterceptTouchEvent ACTION_MOVE11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyButton: dispatchTouchEvent ACTION_MOVE11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyButton: onTouch ACTION_MOVE11-15 05:32:35.314 1584-1584/com.xiey94.view E/MyButton: onTouchEvent ACTION_MOVE11-15 05:32:35.426 1584-1584/com.xiey94.view E/MyLinearLayout: dispatchTouchEvent ACTION_UP11-15 05:32:35.426 1584-1584/com.xiey94.view E/MyLinearLayout: onInterceptTouchEvent ACTION_UP11-15 05:32:35.426 1584-1584/com.xiey94.view E/MyButton: dispatchTouchEvent ACTION_UP11-15 05:32:35.426 1584-1584/com.xiey94.view E/MyButton: onTouch ACTION_UP11-15 05:32:35.426 1584-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

大的流程大概就是这样,至于源码的分析这种活,现在干不了,循序渐进吧!