单选按钮 带角标

https://blog.csdn.net/yoonerloop/article/details/107589057

复制代码
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.AttributeSet;

import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatRadioButton;

/**
 * 单选按钮 带角标
 * https://blog.csdn.net/yoonerloop/article/details/107589057
 */
public class BadgeRadioButton extends AppCompatRadioButton {

    private Paint mPaint;
    private boolean isShowDot;
    private boolean isShowNumberDot;

    //小红点半径
    private final int circleDotRadius = dp2px(4);
    //icon的尺寸,高 == 宽
    private final int drawableSize = dp2px(22);
    //小红点距离icon的padding
    private final int drawablePadding = dp2px(2);
    //矩形角标数字左右padding
    private final int rectFPaddingX = dp2px(4);
    //矩形角标数字上下padding
    private final int rectFPaddingY = dp2px(3);
    //角标矩形背景
    private int rectFRadius = dp2px(8);
    //圆点和角标颜色
    private final int PAINT_COLOR_DEFAULT = Color.parseColor("#FD481E");

    private String numberText;

    /**
     * 圆点和未读消息的坐标
     */
    private float pivotX;
    private float pivotY;

    public BadgeRadioButton(Context context) {
        super(context);
        init();
        updatePadding();
    }

    public BadgeRadioButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
        updatePadding();
    }

    public BadgeRadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
        updatePadding();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setStrokeWidth(2);
        mPaint.setAntiAlias(true);
        mPaint.setColor(PAINT_COLOR_DEFAULT);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(getScrollX(), 0);

        //调整角标位置
        pivotX = getWidth() / 2 + drawableSize / 2 + drawablePadding;
        pivotY = getHeight() / 2 - drawableSize /*/ 2 - drawablePadding*/;

        if (isShowDot) {
            canvas.drawCircle(pivotX, pivotY, circleDotRadius, mPaint);
        } else if (isShowNumberDot && !TextUtils.isEmpty(numberText)) {
            if (Integer.parseInt(numberText) > 99) {
                numberText = "99+";
            }
            if (numberText.length() == 1) {
                rectFRadius = dp2px(6);
            }
            mPaint.setColor(PAINT_COLOR_DEFAULT);
            mPaint.setTextSize(dp2px(12));
            float textWidth = mPaint.measureText(numberText);
            Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
            float textHeight = Math.abs((fontMetrics.top + fontMetrics.bottom));
            RectF rect = new RectF(pivotX - dp2px(4), pivotY - textHeight / 2 - rectFPaddingY, pivotX + textWidth + rectFPaddingX * 2, pivotY + textHeight / 2 + rectFPaddingY);
            canvas.drawRoundRect(rect, rectFRadius, rectFRadius, mPaint);
            mPaint.setColor(Color.parseColor("#ffffff"));
            float baseline = (rect.bottom + rect.top - fontMetrics.bottom - fontMetrics.top) / 2 - dp2px(1);
            mPaint.setTextAlign(Paint.Align.CENTER);
            //绘制文本
            canvas.drawText(numberText, pivotX + textWidth / 2 + rectFPaddingX - dp2px(4) / 2, baseline, mPaint);
        }
    }

    /**
     * `
     * 设置是否显示小圆点
     */
    public void setShowSmallDot(boolean isShowDot) {
        this.isShowDot = isShowDot;
        invalidate();
    }

    /**
     * 设置是否显示数字
     */
    public void setNumberDot(boolean isShowNumberDot, @NonNull String text) {
        this.isShowNumberDot = isShowNumberDot;
        this.numberText = text;
        if (isShowNumberDot) {
            isShowDot = false;
        }
        invalidate();
    }

    private int dp2px(float dpValue) {
        final float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 加一个默认的顶部内边距,否则显示圆点不全
     */
    private void updatePadding() {
        // 获取当前的内边距
        int left = getPaddingLeft();
        int top = getPaddingTop();
        int right = getPaddingRight();
        int bottom = getPaddingBottom();

        // 增加顶部内边距
        int newTopPadding = top + dp2px(12);

        // 设置新的内边距
        setPadding(left, newTopPadding, right, bottom);
    }
}
相关推荐
Colinnian1 小时前
Android Studio创建新项目时需要更改哪些地方
android·ide·android studio
爱埋珊瑚海~~1 天前
Android Studio模拟器一直加载中
android·ide·android studio
编程大师哥1 天前
Android Studio 2025 从性能优化到开发体验下载安装教程安装包
android·ide·android studio
Tom4i1 天前
【内存优化】使用 Android Studio Profiler 分析 .hprof 文件
android·android studio·内存优化·内存泄漏
my_power5202 天前
检出git项目到android studio该如何配置
android·git·android studio
我又来搬代码了5 天前
【Android】【Compose】Compose知识点复习(一)
android·前端·kotlin·android studio
正经教主5 天前
【Trae+AI】和Trae学习搭建App_1.2:第2章·App开发环境配置
android·学习·android studio
WebCsDn_TDCode6 天前
Android Studio使用教程
android·android studio
小蜜蜂嗡嗡6 天前
Android studio配置忽略文件
android·ide·android studio
安果移不动7 天前
git Cherry-Pick合并分支上的某些commits-》Android studio
android·git·android studio