美文网首页
Android画布Canvas--区域Region

Android画布Canvas--区域Region

作者: aruba | 来源:发表于2020-01-13 15:00 被阅读0次

    Canvas类有很多画图形的方法,除了常用的图形外,安卓还提供了Region--区域,表示Canvas图层上一块封闭的区域,可以用于将两个或多个图形做结合,还可以利用contains方法判断坐标、Rect是否在此区域中

    构造方法有以下几种,可以传入一个Region,Rect ,或者上下左右四个坐标
        /** Create an empty region
        */
        public Region() {
            this(nativeConstructor());
        }
    
        /** Return a copy of the specified region
        */
        public Region(Region region) {
            this(nativeConstructor());
            nativeSetRegion(mNativeRegion, region.mNativeRegion);
        }
    
        /** Return a region set to the specified rectangle
        */
        public Region(Rect r) {
            mNativeRegion = nativeConstructor();
            nativeSetRect(mNativeRegion, r.left, r.top, r.right, r.bottom);
        }
    
        /** Return a region set to the specified rectangle
        */
        public Region(int left, int top, int right, int bottom) {
            mNativeRegion = nativeConstructor();
            nativeSetRect(mNativeRegion, left, top, right, bottom);
        }
    
    Region需要和其他Rect、Region、Path、区域结合使用才能发挥效果,拥有下列几种方法
        /** Set the region to the specified region.
        */
        public boolean set(Region region) {
            nativeSetRegion(mNativeRegion, region.mNativeRegion);
            return true;
        }
    
        /** Set the region to the specified rectangle
        */
        public boolean set(Rect r) {
            return nativeSetRect(mNativeRegion, r.left, r.top, r.right, r.bottom);
        }
        
        /** Set the region to the specified rectangle
        */
        public boolean set(int left, int top, int right, int bottom) {
            return nativeSetRect(mNativeRegion, left, top, right, bottom);
        }
    
        /**
         * Set the region to the area described by the path and clip.
         * Return true if the resulting region is non-empty. This produces a region
         * that is identical to the pixels that would be drawn by the path
         * (with no antialiasing).
         */
        public boolean setPath(Path path, Region clip) {
            return nativeSetPath(mNativeRegion, path.readOnlyNI(), clip.mNativeRegion);
        }
    
    而canvas没有画Region的方法,画Region需要使用区域迭代器,它可以将Region区域划分成很多矩形
    /**
     * 演示Region的View
     */
    public class RegionView extends View {
        private Paint mPaint = new Paint();
        
        public RegionView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.RED);
            mPaint.setStyle(Paint.Style.FILL);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            Rect rect =  new Rect(50, 50, 550, 550);
            Region region = new Region(rect);
            Path path = new Path();
            path.addRoundRect(new RectF(rect),300,300, Path.Direction.CCW);
            //将圆形和正方形区域结合
            region.setPath(path,region);
    
            //结合区域迭代器使用(得到图形里面的所有的矩形区域)
            RegionIterator iterator = new RegionIterator(region);
    
            Rect rect1 = new Rect();
            while (iterator.next(rect1)) {
                canvas.drawRect(rect1, mPaint);
            }
        }
    }
    
    drawRect.jpg
    发现和普通的画圆没什么区别,我们将paint的Style改成stroke
    mPaint.setStyle(Paint.Style.STROKE);
    
    drawRect_stroke.jpg
    可以发现一个个矩形,Region用于复杂图形的实现,需要用到图形和图形的叠加,还提供了op()方法
        /**
         * Perform the specified Op on this region and the specified rect. Return
         * true if the result of the op is not empty.
         */
        public boolean op(Rect r, Op op) {
            return nativeOp(mNativeRegion, r.left, r.top, r.right, r.bottom,
                            op.nativeInt);
        }
    
    
        /**
         * Perform the specified Op on this region and the specified rect. Return
         * true if the result of the op is not empty.
         */
        public boolean op(int left, int top, int right, int bottom, Op op) {
            return nativeOp(mNativeRegion, left, top, right, bottom,
                            op.nativeInt);
        }
    
        /**
         * Perform the specified Op on this region and the specified region. Return
         * true if the result of the op is not empty.
         */
        public boolean op(Region region, Op op) {
            return op(this, region, op);
        }
    
        /**
         * Set this region to the result of performing the Op on the specified rect
         * and region. Return true if the result is not empty.
         */
        public boolean op(Rect rect, Region region, Op op) {
            return nativeOp(mNativeRegion, rect, region.mNativeRegion,
                            op.nativeInt);
        }
    
        /**
         * Set this region to the result of performing the Op on the specified
         * regions. Return true if the result is not empty.
         */
        public boolean op(Region region1, Region region2, Op op) {
            return nativeOp(mNativeRegion, region1.mNativeRegion,
                            region2.mNativeRegion, op.nativeInt);
        }
    
    
    其中,我们需要了解的是Op的几种模式
        public enum Op {
            DIFFERENCE(0),
            INTERSECT(1),
            UNION(2),
            XOR(3),
            REVERSE_DIFFERENCE(4),
            REPLACE(5);
    
            Op(int nativeInt) {
                this.nativeInt = nativeInt;
            }
    
            /**
             * @hide
             */
            public final int nativeInt;
        }
    
    下面是不同模式下调用op方法的效果,其中横着的A为调用者,竖着的B为传入参数
    Region_op.png

    相关文章

      网友评论

          本文标题:Android画布Canvas--区域Region

          本文链接:https://www.haomeiwen.com/subject/xlggactx.html