详解android中View绘制过程中的布局

手指拖动一个滑块在屏幕中来回的移动例子:

下载Demo

摘要:通过ViewGroup中的onLayout() 方法来重新布局子类的位置。


自定义ViewCustom继承ViewGroup,重写onLayout()方法,在该方法中调用子类滑块(SquareView)的layout()方法。

    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
        View localView = getChildAt(0);
        if (localView != null) {
            int left = localView.getLeft() + moveX;
            int top = localView.getTop() + moveY;
            Log.d(TAG, "(left, top) = (" + left + "," + top + ")");
            localView.layout(left, top, left + 100, top + 100);
        }

    }

SquareView继承View,重写onDraw(Canvas canvas)方法,绘制一个正方形。

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.WHITE);
        int left = getLeft();
        int top = getTop();
        rfClip = new RectF(left, top, left + 100, top + 100);
        canvas.drawRect(rfClip, mPaint);
    }

两个核心类定义完成,接下来详解整个过程的代码实现。

当手指按到滑块,滑块才会随着手指移动。也就是说手指按在滑块上,才会调用父类ViewCustom中的onLayout()方法。

如何判断手指按到滑动上呢?滑块类SquareView中重写onTouchEvent(MontionEvent event)方法,在该方法中捕获到ACTION_DOWN即可知道手机按在了滑动上。

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                Log.d(TAG, "View 中的ACTION_DOWN事件不处理");
                ViewParent viewParent = getParent();
                if (viewParent instanceof ViewCustom) {
                    ViewCustom localViewCustom = (ViewCustom) viewParent;
                    localViewCustom.SetMoveFlag(true);
                }

            }
            break;
}

在该方法中,调用父类ViewCustom的setMoveFlag()方法,该方法的作用就是设置一个表识来判断手指按在了滑动上。

接下来重写ViewCustom中的onTouchEvent(MotionEvent event)方法。

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE: {

                if (setMoveFlag) {

                    requestLayout();

                }

            }
            break;
            case MotionEvent.ACTION_UP: {

            }
            break;
        }

        return super.onTouchEvent(event);
    }

如果手指按在了滑块上,那么调用requestLayout()方法,该方法是ViewGroup类中的方法,主要作用回调onLayout()方法。

Code过程中发现一个问题,对于事件ACTION_MOVE的理解,当按下屏幕后,不移动手指也会频繁的回调该事件。


猜你喜欢

转载自blog.csdn.net/yuerliang/article/details/80790917