单选按钮 带角标

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);
    }
}
相关推荐
百锦再6 小时前
《易语言学习大全》
开发语言·javascript·python·学习·django·sqlite·android studio
柯南二号17 小时前
Android Studio根目录下创建多个可运行的模块
android·ide·android studio
蓝桉柒72 天前
PHP分页显示数据,在phpMyadmin中添加数据
android·ide·android studio
天花板之恋3 天前
Android Studio Profiler
android studio·trace·profiler
这个家伙很笨4 天前
了解Android studio 初学者零基础推荐(1)
android·笔记·android studio
百锦再5 天前
Android Studio中OpenCV应用详解:图像处理、颜色对比与OCR识别
android·java·图像处理·opencv·kotlin·app·android studio
生如夏花℡6 天前
Android Studio学习记录1
android·学习·android studio
缘来的精彩7 天前
Kotlin与Jetpack Compose的详细使用指南
android·kotlin·android studio·compose·viewmodel
凌云志 !7 天前
Android Studio 2024版,前进返回按钮丢失解决
android·ide·android studio
Yang-Never7 天前
Kotlin -> lateinit 和 lazy 详解
android·开发语言·kotlin·android studio