android 控件绘图和触摸事件分发

布局文件:GroupView继承了FrameLayout,其中层叠了两个View

<com.example.textdemo.view.DTGroupView
        android:id="@+id/dTGroupView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <com.example.textdemo.view.DTView
            android:id="@+id/dTView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <com.example.textdemo.view.DTView1
            android:id="@+id/dTView2"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </com.example.textdemo.view.DTGroupView>


public class DTGroupView extends FrameLayout{
	
	public DTGroupView(Context context) {
		super(context);
	}
	
	public DTGroupView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public DTGroupView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
	}
	
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		Log.i("dt", "group+++dispatchTouchEvent");
		return super.dispatchTouchEvent(ev);
	}
	
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		Log.i("dt", "group+++onInterceptTouchEvent");
		return super.onInterceptTouchEvent(ev);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		Log.i("dt", "group+++onTouchEvent");
		return super.onTouchEvent(event);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		Log.i("dt", "group+++onLayout");
		getChildAt(0).layout(l, t, r, b);
		getChildAt(1).layout(l, t, r, b);
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		Log.i("dt", "group+++onMeasure");
		getChildAt(0).measure(widthMeasureSpec, heightMeasureSpec);
		getChildAt(1).measure(widthMeasureSpec, heightMeasureSpec);
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Log.i("dt", "group+++onDraw");
	}

}



先研究一下绘图方法,日志如下:

03-07 11:15:41.032  4975  4975 I dt      : DTView+++onMeasure

03-07 11:15:41.032  4975  4975 I dt      : DTView1+++onMeasure

03-07 11:15:41.032  4975  4975 I dt      : group+++onMeasure

03-07 11:15:41.032  4975  4975 I dt      : DTView+++onMeasure

03-07 11:15:41.032  4975  4975 I dt      : DTView1+++onMeasure

03-07 11:15:41.035  4975  4975 I dt      : group+++onLayout

03-07 11:15:41.035  4975  4975 I dt      : DTView+++onLayout

03-07 11:15:41.035  4975  4975 I dt      : DTView1+++onLayout

03-07 11:15:41.054  4975  4975 I dt      : DTView+++onDraw

03-07 11:15:41.055  4975  4975 I dt      : DTView1+++onDraw

对比代码我们很好理解,Measure测量方法,从ViewGroup中getChildAt(0)开始测量,然后测量完控件之后,测量ViewGroup本身(多出的测量方法是由于我在代码中调用了一次),Layout布局方法是从最下层空间逐级往上执行。




03-07 11:16:38.609  4975  4975 I dt      : group+++dispatchTouchEvent

03-07 11:16:38.611  4975  4975 I dt      : group+++onInterceptTouchEvent

03-07 11:16:38.614  4975  4975 I dt      : DTView1+++dispatchTouchEvent

03-07 11:16:38.615  4975  4975 I dt      : DTView1+++onTouchEvent

03-07 11:16:38.615  4975  4975 I dt      : DTView+++dispatchTouchEvent

03-07 11:16:38.615  4975  4975 I dt      : DTView+++onTouchEvent

03-07 11:16:38.616  4975  4975 I dt      : group+++onTouchEvent


触摸事件分发机制:首先理解ViewGroup包含dispatch/intercept/onTouchEvent,而View只包含dispatch/onTouchEvent;看日志,dispatch最先执行,然后是onIntercept,如果没有被打断,才继续派发给子控件,子控件最上层首先接收事件,执行dispatch然后onTouch,然后如果返回false则继续派发给下层控件,


猜你喜欢

转载自blog.csdn.net/vcstrong/article/details/60756608
今日推荐