单选按钮 带角标

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);
    }
}
相关推荐
铉铉这波能秀1 天前
如何在Android Studio中使用Gemini进行AI Coding
android·java·人工智能·ai·kotlin·app·android studio
Alex老夫子1 天前
解决 husky > pre-commit hook failed (add --no-verify to bypass)
git·android studio
苏苏码不动了3 天前
Android Studio 虚拟机启动失败/没反应,排查原因。提供一种排查方式。
android·ide·android studio
手机不死我是天子5 天前
《Android 核心组件深度系列 · 第 3 篇 BroadcastReceiver》
android·android studio
fundroid5 天前
Android Studio 新功能 Journey Test:借助 AI 实现基于自然语言的 UI 测试用例编写
android studio
旷野说7 天前
Android Studio Narwhal 3 特性
android·ide·android studio
安卓AndroidQ7 天前
Android Studio 代码混淆核心解释
android·ide·android studio
qq_7391753697 天前
Android Studio 实现四则运算+开方+倒数简易计算器
android·python·android studio
就叫飞六吧7 天前
Android studio -kt构建一个app
android·ide·android studio
QmDeve7 天前
Android内存泄漏排查难?手把手带你用Profiler“揪出”元凶!(附实战案例)
android·android studio