如何在android中使用canvas和matrix重绘布局?

时间:2014-07-01 04:54:48

标签: android animation layout

我想移动并缩放右侧的视图,同时将其拖动到左侧。我尝试在触摸时设置此视图的布局参数。它移动并缩放视图。但是移动手指时渲染不正确快速向左右两侧。

右侧的此视图是自定义布局扩展LinearLayout,其中ListView为子项。左侧也是另一种布局,并将两种布局集成到Framelayout(类似)滑动菜单。)

有没有办法在不更新LayoutParams的情况下渲染视图(移动和缩放)?

是否可以使用画布和矩阵更新布局?

以下是右侧视图(小视图)的自定义布局代码。

public class SlidingLayout extends LinearLayout {

    private static String LOG_TAG = "SlidingLayout";

    private boolean isTranformed = false;

    private PanGestureListener gestureListener;

    private GestureDetector gestureDetector;

    private boolean isAnimating = false;

    private boolean isScrolling = false;

    private DisplayMetrics displayMetrics = getResources().getDisplayMetrics();

    private Matrix matrix = new Matrix();

    private float posX = 0;
    private float posY = 0;

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

    private void init(Context context){
        gestureListener = new PanGestureListener();
        gestureDetector = new GestureDetector(context, gestureListener);
        matrix.setTranslate(0, 0);
        matrix.setScale(1.0f, 1.0f);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //canvas.save();
        /*canvas.drawColor(Color.RED);
        canvas.translate(posX, posY);
        super.onDraw(canvas);*/
        /*canvas.restore();
        matrix.reset();
        matrix = canvas.getMatrix();*/
        /*if (isTranformed) {
            matrix.postTranslate(posX, posY);
            canvas.setMatrix(matrix);
        }
        super.onDraw(canvas);*/
    }

    private void makeViewSmall() {
        if (!isAnimating) {
            isAnimating = true;
            Rect rect = new Rect();
            getLocalVisibleRect(rect);
            ResizeMoveAnimation anim = new ResizeMoveAnimation(this,
                    (int) (displayMetrics.widthPixels * 0.8), displayMetrics.heightPixels / 4,
                    displayMetrics.widthPixels * 2, rect.bottom - displayMetrics.heightPixels
                            / 4);
            anim.setAnimationListener(animationListener);
            anim.setDuration(1000);
            anim.setInterpolator(new BounceInterpolator());
            startAnimation(anim);
        }
    }

    public void makeViewOriginal() {
        if(isTranformed){
            if (!isAnimating) {
                isAnimating = true;
                ResizeMoveAnimation anim = new ResizeMoveAnimation(this, 0, 0,
                        displayMetrics.widthPixels, displayMetrics.heightPixels);
                anim.setAnimationListener(animationListener);
                anim.setInterpolator(new BounceInterpolator());
                anim.setDuration(1000);
                startAnimation(anim);
            }
        }else{
            makeViewSmall();
        }

    }

    private AnimationListener animationListener = new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) CustomSlidingLayout.this .getLayoutParams();
            if (isTranformed) {
                isTranformed = false;
                params.leftMargin = 0;
                params.topMargin =  0;
                params.width = displayMetrics.widthPixels;
                params.height = displayMetrics.heightPixels;
                requestLayout();

            } else {
                isTranformed = true;
            }
            isAnimating = false;
        }
    };

    class PanGestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onSingleTapConfirmed(MotionEvent event) {
            if (isTranformed) {
                makeViewOriginal();
                return true;
            }
            return false;
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (isTranformed) {
            return true;
        } else {
            return false;
        }
    }
    private int _xDelta = 0;
    private int _yDelta = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //gestureDetector.onTouchEvent(event);

        if (isTranformed) {
            final int X = (int) event.getRawX();
            final int Y = (int) event.getRawY();
            switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                this.requestLayout();
                FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) this .getLayoutParams();
                if (layoutParams.leftMargin == 0 && layoutParams.topMargin == 0) {
                    //this.requestLayout();
                    isTranformed = false;
                    isScrolling = false;
                    break;
                }
                isScrolling = true;
                int xDiff = layoutParams.leftMargin - (X - _xDelta);
                layoutParams.leftMargin = X - _xDelta;
                int scaleFactor =  layoutParams.leftMargin > 0 ? layoutParams.leftMargin : 1;
                layoutParams.topMargin = layoutParams.topMargin - ((layoutParams.topMargin / scaleFactor) * xDiff);

                if (layoutParams.leftMargin < 0) {
                    layoutParams.leftMargin = 0;
                }
                if (layoutParams.topMargin < 0) {
                    layoutParams.topMargin = 0;
                }
                layoutParams.width = (displayMetrics.widthPixels - layoutParams.leftMargin);
                layoutParams.height = (displayMetrics.heightPixels - (layoutParams.topMargin * 2));
                this.requestLayout();

                /*final float dx = X - _xDelta;
                final float dy = Y - _yDelta;
                posX += dx;
                posY += dy;
                //matrix.postScale(scaleFactor, scaleFactor,0.0f,0.5f);
                Bitmap bitmap = Bitmap.createBitmap((int)(displayMetrics.widthPixels - posX), (int)(displayMetrics.heightPixels - posY), Config.RGB_565);
                Canvas canvas = new Canvas(bitmap);
                matrix.postTranslate(posX, posY);
                canvas.setMatrix(matrix);
                this.draw(canvas);
                _xDelta = X;
                _yDelta = Y;
                invalidate();*/
                break;

            case MotionEvent.ACTION_UP:
                isScrolling = false;

                break;

            case MotionEvent.ACTION_DOWN:
                FrameLayout.LayoutParams lParams = (FrameLayout.LayoutParams) this
                        .getLayoutParams();
                _xDelta = X - lParams.leftMargin;
                _yDelta = X - lParams.topMargin;
                posX  = 0;
                posY = 0;
                break;
            }
            return true;
        }
        return true;
    }
}

1 个答案:

答案 0 :(得分:0)

您可以致电invalidate()中的onTouch()来执行onDraw()中的代码以重绘视图。

invalidate()将强制绘制视图。