• 自定义控件之canvas变换和裁剪


    1.平移

     //构造两个画笔,一个红色,一个绿色
            Paint paint_green = generatePaint(Color.GREEN, Paint.Style.STROKE, 3);
            Paint paint_red   = generatePaint(Color.RED, Paint.Style.STROKE, 3);
    
            //构造一个矩形
            Rect rect1 = new Rect(0,0,400,220);
    
            //在平移画布前用绿色画下边框
            canvas.drawRect(rect1, paint_green);
    
            //平移画布后,再用红色边框重新画下这个矩形
            canvas.translate(100, 100);
            canvas.drawRect(rect1, paint_red);

    2.旋转

     Paint paint_green = generatePaint(Color.GREEN, Paint.Style.FILL, 5);
            Paint paint_red   = generatePaint(Color.RED, Paint.Style.STROKE, 5);
    
            Rect rect1 = new Rect(300,10,500,100);
            canvas.drawRect(rect1, paint_red); //画出原轮廓
    
            canvas.rotate(30);//顺时针旋转画布
            canvas.drawRect(rect1, paint_green);//画出旋转后的矩形

    3.缩放

         Paint paint_green = generatePaint(Color.GREEN, Paint.Style.STROKE, 5);
            Paint paint_red   = generatePaint(Color.RED, Paint.Style.STROKE, 5);
            Paint paint_yellow   = generatePaint(Color.YELLOW, Paint.Style.STROKE, 5);
    
            Rect rect1 = new Rect(10,10,200,100);
            canvas.drawRect(rect1, paint_green);
    
            canvas.scale(0.5f, 1);
            canvas.drawRect(rect1, paint_red);

    4.扭曲

     Paint paint_green = generatePaint(Color.GREEN, Paint.Style.STROKE, 5);
            Paint paint_red   = generatePaint(Color.RED, Paint.Style.STROKE, 5);
    
            Rect rect1 = new Rect(10,10,200,100);
    
            canvas.drawRect(rect1, paint_green);
            canvas.skew(1.732f,0);//X轴倾斜60度,Y轴不变
            canvas.drawRect(rect1, paint_red);

    5.裁剪

     canvas.drawColor(Color.RED);
            //保存的画布大小为全屏幕大小
            int c1 = canvas.save();
    
            canvas.clipRect(new Rect(100, 100, 800, 800));
            canvas.drawColor(Color.GREEN);
            //保存画布大小为Rect(100, 100, 800, 800)
            int c2 = canvas.save();
    
            canvas.clipRect(new Rect(200, 200, 700, 700));
            canvas.drawColor(Color.BLUE);
            //保存画布大小为Rect(200, 200, 700, 700)
            int c3 = canvas.save();
    
            canvas.clipRect(new Rect(300, 300, 600, 600));
            canvas.drawColor(Color.BLACK);
            //保存画布大小为Rect(300, 300, 600, 600)
            int c4 = canvas.save();
    
            canvas.clipRect(new Rect(400, 400, 500, 500));
            canvas.drawColor(Color.WHITE);
    
            //连续出栈三次,将最后一次出栈的Canvas状态作为当前画布,并画成黄色背景
            canvas.restoreToCount(c2);
            canvas.drawColor(Color.YELLOW);

    获取画笔方法

      private Paint generatePaint(int color,Paint.Style style,int width){
            Paint paint = new Paint();
            paint.setColor(color);
            paint.setStyle(style);
            paint.setStrokeWidth(width);
            return paint;
        }

    画布的保存和恢复

    canvas.save()
    canvas.restore();

    save()每次调用save函数,都会先保存画布的状态,然后将其放入特定的栈中

    restore()都会把栈中顶层的画布状态取出来,并按照这个状态恢复当前的画布,然后在这个画布上作画

    restoreToCount函数
    restoreToCount(int saveCount)
            int c2 = canvas.save();//返回栈的索引
            canvas.restoreToCount(c2);//根据索引返回当前画布

    示例代码-圆形代码

    public class BasisView extends View {
    
        private Bitmap mBmp;
        private Paint mPaint;
        private Path mPath;
        public BasisView(Context context) {
            super(context);
            init();
        }
    
        public BasisView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public BasisView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init(){
            setLayerType(LAYER_TYPE_SOFTWARE,null);
            mBmp = BitmapFactory.decodeResource(getResources(), R.drawable.avator);
            mPaint = new Paint();
            mPath = new Path();
            int width = mBmp.getWidth();
            int height = mBmp.getHeight();
            mPath.addCircle(width/2,height/2,width/2, Path.Direction.CCW);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.save();
            canvas.clipPath(mPath);
            canvas.drawBitmap(mBmp,0,0,mPaint);
            canvas.restore();
    
        }
    
    }

    裁剪动画

    package com.loaderman.customviewdemo.paint;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.RectF;
    import android.graphics.Region;
    import android.support.annotation.Nullable;
    import android.util.AttributeSet;
    import android.view.View;
    
    import com.loaderman.customviewdemo.R;
    
    
    public class BasisView extends View {
        private Path mPath;
        private Bitmap mBitmap;
        private int clipWidth = 0;
        private int width;
        private int heigth;
        private static final int CLIP_HEIGHT = 30;
        private Region mRgn;
        public BasisView(Context context) {
            super(context);
            init();
        }
        public BasisView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
        public BasisView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
        private void init() {
            setLayerType(LAYER_TYPE_SOFTWARE, null);
            mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.avator);
            width = mBitmap.getWidth();
            heigth = mBitmap.getHeight();
            mRgn = new Region();
            mPath=new Path();
        }
        @Override
        protected void onDraw(Canvas canvas) {
            mRgn.setEmpty();
            int i = 0;
            while (i * CLIP_HEIGHT <= heigth) {
                if (i % 2 == 0) {
                    mPath.addRect(new RectF(0, i * CLIP_HEIGHT, clipWidth, (i + 1) * CLIP_HEIGHT),Path.Direction.CCW);
                } else {
                    mPath.addRect(new RectF(width - clipWidth, i * CLIP_HEIGHT, width, (i + 1) * CLIP_HEIGHT),Path.Direction.CCW);
                }
                i++;
            }
            canvas.clipPath(mPath);
            canvas.drawBitmap(mBitmap, 0, 0, new Paint());
            if (clipWidth > width) {
                return;
            }
            clipWidth += 5;
            invalidate();
        }
       
    }

    效果:

  • 相关阅读:
    Hanlp(汉语言处理包)配置、使用、官方文档
    Mysql 在DOS窗口下的操作
    漂亮的省级下拉选择
    数组的应用排序
    设置外部样式坐标的位置
    动态设置Div坐标
    对联广告
    树形菜单
    隐藏图和图框架
    使用clssneme改变图片或样式
  • 原文地址:https://www.cnblogs.com/loaderman/p/10191656.html
Copyright © 2020-2023  润新知