安卓圆角背景遮罩。覆盖实现方式(适用于所有控件)

Posted WidgetBox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓圆角背景遮罩。覆盖实现方式(适用于所有控件)相关的知识,希望对你有一定的参考价值。

1.工具类直接用(已经改好)

package com.etwod.yulin.t4.unit;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.support.annotation.ColorInt;
import android.util.AttributeSet;
import android.view.View;

import com.etwod.yulin.android.R;

/**
 * A circular cover view.Above other views to hide the conner.You can set radians by self.
 * Created by
 * 磊磊tua
 * 覆盖形成圆角
 */
public class CircularCoverView extends View {

    private int leftTopRadians = 30;        //leftTopRadians
    private int leftBottomRadians = 30;     //leftBottomRadians
    private int rightTopRadians = 30;       //rightTopRadians
    private int rightBottomRadians = 30;    //rightBottomRadians

    private int coverColor = 0xffeaeaea;    //color of cover.

    public CircularCoverView(Context context) {
        this(context, null, 0);
    }

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

    public CircularCoverView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularCoverView);
        leftTopRadians = typedArray.getDimensionPixelSize(R.styleable.CircularCoverView_left_top_radius, leftTopRadians);
        leftBottomRadians = typedArray.getDimensionPixelSize(R.styleable.CircularCoverView_left_bottom_radius, leftBottomRadians);
        rightTopRadians = typedArray.getDimensionPixelSize(R.styleable.CircularCoverView_right_top_radius, rightTopRadians);
        rightBottomRadians = typedArray.getDimensionPixelSize(R.styleable.CircularCoverView_right_bottom_radius, rightBottomRadians);
        coverColor = typedArray.getColor(R.styleable.CircularCoverView_cover_color, coverColor);
    }

    /**
     * set radians of cover.
     */
    public void setRadians(int leftTopRadians, int rightTopRadians, int leftBottomRadians, int rightBottomRadians) {
        this.leftTopRadians = leftTopRadians;
        this.rightTopRadians = rightTopRadians;
        this.leftBottomRadians = leftBottomRadians;
        this.rightBottomRadians = rightBottomRadians;
    }

    /**
     * set color of cover.
     *
     * @param coverColor cover‘s color
     */
    public void setCoverColor(@ColorInt int coverColor) {
        this.coverColor = coverColor;
    }

    /**
     * create a sector-bitmap as the dst.
     *
     * @param w width of bitmap
     * @param h height of bitmap
     * @return bitmap
     */
    private Bitmap drawSector(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setColor(0xFFFFCC44);//notice:cannot set transparent color here.otherwise cannot clip at final.

        c.drawArc(new RectF(0, 0, leftTopRadians * 2, leftTopRadians * 2), 180, 90, true, p);
        c.drawArc(new RectF(0, getHeight() - leftBottomRadians * 2, leftBottomRadians * 2, getHeight()), 90, 90, true, p);
        c.drawArc(new RectF(getWidth() - rightTopRadians * 2, 0, getWidth(), rightTopRadians * 2), 270, 90, true, p);
        c.drawArc(new RectF(getWidth() - rightBottomRadians * 2, getHeight() - rightBottomRadians * 2, getWidth(), getHeight()), 0, 90, true, p);
        return bm;
    }

    /**
     * create a rect-bitmap as the src.
     *
     * @param w width of bitmap
     * @param h height of bitmap
     * @return bitmap
     */
    private Bitmap drawRect(int w, int h) {
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bm);
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setColor(coverColor);

        c.drawRect(new RectF(0, 0, leftTopRadians, leftTopRadians), p);
        c.drawRect(new RectF(0, getHeight() - leftBottomRadians, leftBottomRadians, getHeight()), p);
        c.drawRect(new RectF(getWidth() - rightTopRadians, 0, getWidth(), rightTopRadians), p);
        c.drawRect(new RectF(getWidth() - rightBottomRadians, getHeight() - rightBottomRadians, getWidth(), getHeight()), p);
        return bm;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setFilterBitmap(false);
        paint.setStyle(Paint.Style.FILL);

        //create a canvas layer to show the mix-result
        int sc = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.MATRIX_SAVE_FLAG |
                Canvas.CLIP_SAVE_FLAG |
                Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
                Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
                Canvas.CLIP_TO_LAYER_SAVE_FLAG);

        //draw sector-dst-bitmap at first.
        canvas.drawBitmap(drawSector(getWidth(), getHeight()), 0, 0, paint);
        //set Xfermode of paint.
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
        //then draw rect-src-bitmap
        canvas.drawBitmap(drawRect(getWidth(), getHeight()), 0, 0, paint);
        paint.setXfermode(null);
        //restore the canvas
        canvas.restoreToCount(sc);
    }
}

2.在attrs 进行配置

  <!-- 圆角遮罩-->
    <declare-styleable name="CircularCoverView">

    <attr name="left_top_radius" format="dimension"/>

    <attr name="left_bottom_radius" format="dimension"/>

    <attr name="right_top_radius" format="dimension"/>

    <attr name="right_bottom_radius" format="dimension"/>

    <attr name="cover_color" format="color"/>

</declare-styleable>

3.控件的两种用法

<1>在布局文件的用法 只需在布局设置就好了(注意:必须用相对布局实现)

相对布局
 <com.etwod.yulin.t4.unit.CircularCoverView
            android:id="@+id/ccv_ads"
            android:layout_width="match_parent"
            android:layout_height="180dp"
            app:cover_color="@color/red"
            app:left_bottom_radius="9dp"
            app:left_top_radius="9dp"
            app:right_bottom_radius="9dp"
            app:right_top_radius="9dp" />
left_bottom_radius
left_top_radius
right_bottom_radius
right_top_radius
分别代表左下 左上 右下 右上
<2>在布局文件的用法 只需在布局设置
RelativeLayout container = new RelativeLayout(this);
//create other child views...
CircularCoverView coverView = new CircularCoverView(this);
coverView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
coverView.setCoverColor(Color.WHITE);
coverView.setRadians(35, 35, 35, 35);
container.addView(coverView);

非常好用 不受任何限制,其他不能实现首选推荐!!!

by:磊磊tua

 

 




以上是关于安卓圆角背景遮罩。覆盖实现方式(适用于所有控件)的主要内容,如果未能解决你的问题,请参考以下文章

安卓中遮罩图片的处理

Android学习笔记圆角矩形ImageView自定义控件的实现与使用

qt圆角按钮与图片背景冲突

Android圆角Tag控件的另类实现

Android圆角背景设置

WPF 项目版本控制以及布局控件