万能圆角

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

  /**
     * 获得圆角图片
     * @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自定义属性的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--万能圆角的自定义属性-->
    <declare-styleable name="RoundTextView">
        <attr name="paintColor" format="color"/>
        <attr name="tvRadio" format="dimension"/>
    </declare-styleable>
</resources>

在布局文件中使用如下:

<RelativeLayout
  android:layout_width="wrap_content"
  app:layout_constraintTop_toBottomOf="@+id/et"
  app:layout_constraintRight_toRightOf="parent"
  app:layout_constraintLeft_toLeftOf="parent"
  android:layout_marginTop="20dp"
  android:layout_height="200dp">
  <!--目标圆角控件-->
  <TextView
      app:layout_constraintTop_toTopOf="parent"
      android:layout_width="200dp"
      android:layout_height="200dp"
      android:textSize="15sp"
      android:gravity="center"
      android:text="代替图片圆角的控件"
      android:background="#00ff00"/>
  <!--盖在目标圆角控件上的万能圆角类-->
  <com.xxx.demo.myview.RoundTextView
      android:id="@+id/rtv"
      android:layout_width="200dp"
      android:layout_height="200dp"
      android:clickable="true"
      app:paintColor="#ff0000"
      app:tvRadio="100dp"
      />
</RelativeLayout>

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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值