万能圆角

前言:我们项目当中经常碰到要对某个图片控件做成圆角,或者动态改变它的圆角率,一般的做法如下

  /**
     * 获得圆角图片
     * @param bitmap
     * @param roundPx
     * @return
     * Bitmap.createBitmap 很容易出现oom,尽量不要使用
     */
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final Paint paint = new Paint();
        paint.setAntiAlias(true);
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

但是此种方式一直在createBitmap容易出现性能问题,于是我就在想,有没有不会出现性能问题而且还可以通用的方式呢,基于此,下面的万能圆角类诞生了
万能圆角类:
1.支持静态文件配置属性,
2.支持动态代码改圆角率,
3.支持所有的控件而不是图片控件
完整的代码如下:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.TextView;
import com.xxx.demo.R;

/**
 * Created by xxx on 2019/1/27.
 */
public class RoundTextView extends TextView {
    Paint	outPaint;
    int paintColor=Color.WHITE,tvRadio=21;
    Path path1,path2;
    RectF outRect;

    public RoundTextView(Context context) {
        super(context);
        initPaint(context, null);
    }

    public RoundTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint(context, attrs);
    }

    public RoundTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs);
        initPaint(context, attrs);
    }
    
 private void initPaint(Context context, AttributeSet attrs) {
        //自定义属性
        //outPaint的颜色值 ,圆角率
        if (attrs!=null) {
            TypedArray ta= context.obtainStyledAttributes(attrs, R.styleable.RoundTextView);
            paintColor = ta.getColor(R.styleable.RoundTextView_paintColor, Color.WHITE);
            tvRadio= ta.getDimensionPixelSize(R.styleable.RoundTextView_tvRadio,21);
            ta.recycle();
        }

        if(outPaint==null){
            outPaint = new Paint();
            outPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            outPaint.setAntiAlias(true);
            outPaint.setColor(paintColor);
        }
        
        if (path1==null) {
            path1 = new Path();
            path2 = new Path();
        }
        
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed) {
            outRect=new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());
        }
    }


    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        path1.reset();
        path2.reset();
        path1.addRect(outRect,Path.Direction.CW);
        path2.addRoundRect(outRect,tvRadio,tvRadio,Path.Direction.CW);

        if (Build.VERSION.SDK_INT >= 19) {
            path1.op(path2, Path.Op.DIFFERENCE );
        }
        canvas.drawPath(path1, outPaint);
        canvas.restore();
        super.onDraw(canvas);
    }

    public void setRadio(int radio) {
        tvRadio = radio;
        requestLayout();
    }

   public void setColor(int color){
       if (outPaint!=null) {
           outPaint.setColor(color);
       }
       requestLayout();
   }

    /**
     * @param color;#ff0000
     */
   public void setColor(String color){
       if (outPaint!=null) {
           outPaint.setColor(Color. parseColor(color));
       }
       requestLayout();
   }   
}

在res–>values–>attrs自定义属性的代码如下:



    
    
        
        
    

在布局文件中使用如下:


  
  
  
  

注意这里使用了app命名空间,记得加这句话
xmlns:app=“http://schemas.android.com/apk/res-auto”
实现效果如下:
万能圆角_第1张图片万能圆角_第2张图片
说明:
1,把红色设置成圆角控件的背景颜色,就可以看起来是圆角
2,实现的原理是:在要实现圆角控件的上面放一个遮住4个角的控件,而4个角的控件是通过path.addXXX然后取2个path的交集或者并集而得到的(其实利用path.op可以得到很多好玩的图形 path1.op(path2, Path.Op.DIFFERENCE,具体可自行百度 );

你可能感兴趣的:(Android基础总结)