单选按钮 带角标

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);
    }
}
相关推荐
青蛙娃娃8 小时前
漫画Android:动画是如何实现的?
android·android studio
hashiqimiya1 天前
android studio底部导航栏
android·ide·android studio
ThMoonAdSixPence1 天前
在Android Studio中复现AOSP原生GL2JNI图形渲染应用
android·android studio
帅次1 天前
Flutter setState() 状态管理详细使用指南
android·flutter·ios·小程序·kotlin·android studio·iphone
hashiqimiya2 天前
android studio向左向右滑动页面
android studio
我命由我123452 天前
Android Studio 问题:Android Studio 一直开在 Updating indexes
android·java·ide·java-ee·android studio·android jetpack·android-studio
编程乐学3 天前
基于Android 开发完成的购物商城App--前后端分离项目
android·android studio·springboot·前后端分离·大作业·购物商城
这个家伙很笨3 天前
了解Android studio 初学者零基础推荐(4)
android·ide·android studio
hashiqimiya3 天前
android studio中修改java逻辑对应配置的xml文件
xml·java·android studio
5upport3 天前
Gradle Version Catalog的IDE辅助工具
gradle·android studio·intellij idea