自定义View实现圆角化

目的:

1.实现自定义ReleativeLayout圆角化

实现:

1.在res目录中新建attrs.xml文件,自定义属性如下。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundBgRelativeLayout">
        <attr name="borderRadius" format="dimension"/><!-- 半径-->
        <attr name="src" format="reference"/><!-- 图片资源-->
    </declare-styleable>
</resources>

2.新建自定义Layout继承RelativeLayout,重写构造方法。

public class RoundBgRelativeLayout extends RelativeLayout {

    /**
     * 圆角大小
     */
    private int mRadius;

    /**背景图片*/
    private Bitmap mSrc;

    public RoundBgRelativeLayout(Context context) {
        this(context,null);
    }

    public RoundBgRelativeLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public RoundBgRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setWillNotDraw(false);
        TypedArray arr = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RoundBgRelativeLayout, defStyleAttr, 0);
        int indexCount = arr.getIndexCount();
        for (int i = 0; i < indexCount; i++) {
            int index = arr.getIndex(i);
            switch (index){
                case R.styleable.RoundBgRelativeLayout_src:
                    mSrc = BitmapFactory.decodeResource(getResources(), arr.getResourceId(index, 0));
                    break;
                case R.styleable.RoundBgRelativeLayout_borderRadius:
                    mRadius= (int) arr.getDimension(index,20);
                    break;
                default:
                    break;
            }

        }
        arr.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(mSrc != null){
            int width = getMeasuredWidth();//测量宽度
            int height = getMeasuredHeight();//测量高度
            mSrc = Bitmap.createScaledBitmap(mSrc,width,height,false);
            canvas.drawBitmap(createRoundImage(mSrc,width,height),0,0,null);//绘制圆角背景
        }
        super.onDraw(canvas);
    }

    private Bitmap createRoundImage(Bitmap mSrc, int width, int height) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        Bitmap target = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(target);
        RectF rectF = new RectF(0,0,width,height);

        //绘制圆角矩形
        canvas.drawRoundRect(rectF,mRadius,mRadius,paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//该模式可以让两个重叠,并取交集
        //绘制图片
        canvas.drawBitmap(mSrc,0,0,paint);

        return target;
    }

    public void setBgResource(int r){
        this.mSrc = BitmapFactory.decodeResource(getResources(),r);
        invalidate();
    }
}

实现原理:

主要靠PorterDuff.Mode.SRC_IN 这种模式,第一个图绘制为圆角矩形,第二个图绘制是个BItmap,两者取交集,就实现了圆形图片的效果。

PorterDuff.Mode 16种效果图,如下。

最终实现:

参考

1.鸿神:http://blog.csdn.net/lmj623565791/article/details/24555655

2.https://blog.csdn.net/fhkatuz674/article/details/39271581

 

猜你喜欢

转载自www.cnblogs.com/fangg/p/11083230.html