Android 小红点 未读消息功能 BadgeHelper

本文介绍了如何在Android项目中实现一个兼容各种布局的小红点未读消息功能,作者通过创建BadgeHelper类,避免了小红点与目标视图重叠的问题,提供重叠和非重叠两种模式。文章包含核心类BadgeHelper.java的使用示例,适合开发者参考学习。
摘要由CSDN通过智能技术生成

Android 小红点 未读消息功能 BadgeHelper

因为最近的项目需求,翻遍github上的未读消息红点开源库, 发现大部分
不能适配不同情况的布局, 所以我写了一个能兼容全部的 !
网上的写法是 继承TextView然后生成一个小红点drawable,设置到背景中去, 然后把目标view外层加一层FrameLayout,然后把小红点添加进去
但这样做的问题来了, 小红点与目标View 会叠起来!, 挡住文字,!!! 看得我瞎了~~~ 而且 他们提供的setOffsetX setpadding 之类的没卵用,你如果想要偏移小红点让它不与下面的View重叠,那是不可能的
所以我的写法是 为了更好的性能,直接继承View然后画小红点背景, 然后把目标view外层加一层LinearLayout 让小红点View放目标的右边,这样就不会重叠
同时 我也支持设置 重叠模式和非重叠模式

这是效果图
这里写图片描述

由于github账号出问题了,没法上传, 所以写到博客上算了

这只是一个小工具类 供大家学习下我的思路, 就不多说了, 具体实现注释里写的很清楚,不太清楚的可以回复问我

#核心类:
##BadgeHelper .java

 
package com.truescend.gofit.views;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.IntDef;
import android.support.design.widget.TabLayout;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;

/**
 * 作者:东芝(2018/8/23).
 * 支持 重叠目标模式 和 放目标右上角但不重叠的模式 两种模式 通过setOverlap 设置,  默认为false=不重叠
 */

public class BadgeHelper extends View {
   
    private static final String TAG = "BadgeHelper";
    private float density;
    private Paint mTextPaint;
    private Paint mBackgroundPaint;
    private String text = "0";
    private int number;

    @Type
    private int type = Type.TYPE_POINT;
    private boolean isOverlap;
    private final RectF rect = new RectF();
    private int badgeColor = 0xFFD3321B; //默认的小红点颜色
    private int textColor = 0xFFFFFFff;
    private float textSize;
    private int w;
    private int h;
    private boolean isSetup;
    private boolean mIgnoreTargetPadding;
    private boolean isCenterVertical;
    private int leftMargin;
    private int topMargin;
    private int rightMargin;
    private int bottomMargin;

    @IntDef({
   Type.TYPE_POINT, Type.TYPE_TEXT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Type {
   
        int TYPE_POINT = 0;
        int TYPE_TEXT = 1;
    }


    public BadgeHelper(Context context) {
   
        super(context);

    }


    private void init(@Type int type, boolean isOverlap) {
   
        this.type = type;
        this.isOverlap = isOverlap;
        density = getResources().getDisplayMetrics().density;

        switch (type) {
   
            case Type.TYPE_POINT:
                mBackgroundPaint = new Paint();
                mBackgroundPaint.setStyle(Paint.Style.FILL);
                mBackgroundPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
                mBackgroundPaint.setColor(badgeColor);
                //计算小红点无文本情况下的小红点大小,  按屏幕像素计算, 如果你有你自己认为更好的算法, 改这里即可
                w = h = Math.round(density * 7f);
                break;
            case Type.TYPE_TEXT:
                mBackgroundPaint = new Paint();
                mBackgroundPaint.setStyle(Paint.Style.FILL);
                mBackgroundPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
                mBackgroundPaint.setColor(badgeColor);

                mTextPaint = new Paint();
                mTextPaint.setStyle(Paint.Style.FILL);
                mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
                mTextPaint.setColor(textColor);//文本颜色
                if (textSize == 0) {
   
                    mTextPaint.setTextSize(density * 10);//文本大小按屏幕像素 计算, 没写死是为了适配各种屏幕,  但如果你有你认为更合理的计算方式 你可以改这里
                } else {
   
                    mTextPaint.setTextSize(textSize);//使用自定义大小
                }

                //计算小红点有文本情况下的小红点大小,  按文本宽高计算, 如果你有你自己认为更好的算法, 改这里即可
                float textWidth = getTextWidth("99", mTextPaint);
                w = h = Math.round(textWidth * 1.4f);//让背景比文本大一点
                break;
        }
    }

    /**
     * 设置Margin 可用于做偏移
     * @param left
     * @param top
     * @param right
     * @param bottom
     * @return
     */
    public BadgeHelper setBadgeMargins(int left, int top, int right, int bottom) {
   
        leftMargin = left;
        topMargin = top;
        rightMargin = right;
        bottomMargin = bottom;
        return this;
    
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值