Code Monkey home page Code Monkey logo

roundangleframelayout's Introduction

##android 通用圆角控件

红色字为总结日记--写给未来的我

圆角控件就是对 View的Canvas进行改变轮廓的处理 改变轮廓两种方式: 1.剪切(clip()) 剪切clip是对画布进行剪切,只对剪切后的绘制起效果。 ps:Canvas的图形变换平移、放缩、旋转、错切、裁剪都是只对后面的绘制起效果, 对应Matrix中preXXX,Matrix变换分为preXXX,postXXX,setXXX;preXXX将新的变换操作插到队列前,postXXX将新的变换操作插到队列后,setXXX是先reset()清除前面的变换操作并设置新的变换操作,且都是只对后面的绘制起效果。 Canvas的save,restore对变换操作进行保存,和还原,带参的restoreToCount(save()),可以指定还原到第几次保存的状态。 2.遮罩(PorterDuffXfermode) 安卓提供多种遮罩模式选择 这里写图片描述 遮罩是设置在Paint上的只对 当前绘制的操作有效

####下面利用这两种方式实现圆角控件 onDraw onDrawForeground dispatchDraw 这三个回调函数都是可以操作View的Canvas;onDraw,onDrawForeground这两个是在View绘制背景,自身内容和前景时回调的 只有设置了背景、自身内容、前景时才会配回调,并且对这两个函数的参数Canvas上的操作,只对背景、自身内容、前景有效。 dispatchDraw是绘制子控件时的回调,参数Canvas可以对子控件的画布进行处理。 通用圆角控件必须对子控件的对应位置也是原价所以我门选择在dispatchDraw中进行圆角处理。

剪切(clip())

    @Override
    protected void dispatchDraw(Canvas canvas) {
        int width = getWidth();
        int height = getHeight();
        Path path = new Path();
        path.moveTo(0, topLeftRadius);
        path.arcTo(new RectF(0, 0, topLeftRadius * 2, topLeftRadius * 2), -180, 90);
        path.lineTo(width - topRightRadius, 0);
        path.arcTo(new RectF(width - 2 * topRightRadius, 0, width, topRightRadius * 2), -90, 90);
        path.lineTo(width, height - bottomRightRadius);
        path.arcTo(new RectF(width - 2 * bottomRightRadius, height - 2 * bottomRightRadius, width, height), 0, 90);
        path.lineTo(bottomLeftRadius, height);
        path.arcTo(new RectF(0, height - 2 * bottomLeftRadius, bottomLeftRadius * 2, height), 90, 90);
        path.close();
        canvas.clipPath(path);
        super.dispatchDraw(canvas);
    }

效果图: 这里写图片描述

上图能看到明显的锯齿 因为 安卓虽提供了抗锯齿功能但是是在Paint上操作的 clip过程没有用到Paint 无法达到抗锯齿目的;

遮罩(PorterDuffXfermode)

####写法一

 @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        drawTopLeft(canvas);//用PorterDuffXfermode
        drawTopRight(canvas);//用PorterDuffXfermode
        drawBottomLeft(canvas);//用PorterDuffXfermode
        drawBottomRight(canvas);//用PorterDuffXfermode
    }

效果图: 这里写图片描述

上图有黑色底色,view的Canvas底层画布的BItmap是 RGB_565的所以怎么画都有一个黑色底色。

我们可以new Canvas一个底层画布的BItmap是 ARGB_8888的绘制完后 再把这个底层画布的BItmap 绘制到View 的Canvas上

####写法二

    @Override
    protected void dispatchDraw(Canvas canvas) {
        Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas newCanvas = new Canvas(bitmap);
        super.dispatchDraw(newCanvas);
        drawTopLeft(newCanvas);
        drawTopRight(newCanvas);
        drawBottomLeft(newCanvas);
        drawBottomRight(newCanvas);
        canvas.drawBitmap(bitmap,0,0,imagePaint);
//        invalidate();
    }

效果图: 这里写图片描述

实现了,但是这种映射方式实现的 如果子控件中存在滑动控件,滑动时无法实时刷新,用Glide加载image到ImageView中时,WebView load时 都无法实时刷新,出现无法加载的效果,虽然可以加上invalidate通知刷新 但是掉帧明显

我们只能用回写法一 但是要解决黑色背景的问题 只要加上一句代码 就能解决 默认黑色背景的问题

canvas.saveLayer(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), imagePaint,Canvas.ALL_SAVE_FLAG);
 @Override
    protected void dispatchDraw(Canvas canvas) {
canvas.saveLayer(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), imagePaint,Canvas.ALL_SAVE_FLAG);
        super.dispatchDraw(canvas);
        drawTopLeft(canvas);//用PorterDuffXfermode
        drawTopRight(canvas);//用PorterDuffXfermode
        drawBottomLeft(canvas);//用PorterDuffXfermode
        drawBottomRight(canvas);//用PorterDuffXfermode
        canvas.restore();
    }

效果图: 这里写图片描述

因为view的Canvas底层画布的BItmap是 RGB_565 我们只要在保存为图层就行了。用过Photoshop的都知道默认底层画布是不透明的,要先解锁,而这里解锁就是保存为图层。

相关链接:http://blog.csdn.net/oyuanwa/article/details/51197546

roundangleframelayout's People

Contributors

pierre-primary avatar y-bao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.