Android实现消息提醒小红点效果

本人分享一下,自己写的一个消息提醒小红点控件,支持圆、矩形、椭圆、圆角矩形、正方形五种图形样式,可带文字,支持链式操作。

先看一下实现效果,随便测了几个控件(TextView、ImageView、RadioButton、LinearLayout、RelativeLayout、FrameLayout),不确定其他会不会有问题。

import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TabWidget; public class BadgeView extends View { protected static final String LOG_TAG = "BadgeView"; // 该控件的背景图形类型 public static final int SHAPE_CIRCLE = 1; public static final int SHAPE_RECTANGLE = 2; public static final int SHAPE_OVAL = 3; public static final int SHAPTE_ROUND_RECTANGLE = 4; public static final int SHAPE_SQUARE = 5; // 该框架内容的文本画笔 private Paint mTextPaint; // 该控件的背景画笔 private Paint mBgPaint; private int mHeight = 0; private int mWidth = 0; private int mBackgroundShape = SHAPE_CIRCLE; private int mTextColor = Color.WHITE; private int mTextSize; private int mBgColor = Color.RED; private String mText = ""; private int mGravity = Gravity.RIGHT | Gravity.TOP; private RectF mRectF; private float mtextH; private boolean mIsShow = false; public BadgeView(Context context) { this(context, null); } public BadgeView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public BadgeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mRectF = new RectF(); mTextSize = dip2px(context, 1); mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPaint.setColor(mTextColor); mTextPaint.setStyle(Paint.Style.FILL); mTextPaint.setTextSize(mTextSize); mTextPaint.setTextAlign(Paint.Align.CENTER); mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mBgPaint.setColor(mBgColor); mBgPaint.setStyle(Paint.Style.FILL); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); params.gravity = mGravity; setLayoutParams(params); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mRectF.set(0, 0, getMeasuredWidth(), getMeasuredHeight()); Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); mtextH = fontMetrics.descent - fontMetrics.ascent; switch (mBackgroundShape) { case SHAPE_CIRCLE: canvas.drawCircle(getMeasuredWidth() / 2f, getMeasuredHeight() / 2f, getMeasuredWidth() / 2, mBgPaint); canvas.drawText(mText, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f + (mtextH / 2f - fontMetrics.descent), mTextPaint); break; case SHAPE_OVAL: canvas.drawOval(mRectF, mBgPaint); canvas.drawText(mText, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f + (mtextH / 2f - fontMetrics.descent), mTextPaint); break; case SHAPE_RECTANGLE: canvas.drawRect(mRectF, mBgPaint); canvas.drawText(mText, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f + (mtextH / 2f - fontMetrics.descent), mTextPaint); break; case SHAPE_SQUARE: int sideLength = Math.min(getMeasuredHeight(), getMeasuredWidth()); mRectF.set(0, 0, sideLength, sideLength); canvas.drawRect(mRectF, mBgPaint); canvas.drawText(mText, sideLength / 2f, sideLength / 2f + (mtextH / 2f - fontMetrics.descent), mTextPaint); break; case SHAPTE_ROUND_RECTANGLE: canvas.drawRoundRect(mRectF, dip2px(getContext(), getMeasuredWidth()/2), dip2px(getContext(), getMeasuredWidth()/2), mBgPaint); canvas.drawText(mText, getMeasuredWidth() / 2f, getMeasuredHeight() / 2f + (mtextH / 2f - fontMetrics.descent), mTextPaint); break; } } /** * 设置该控件的背景颜色 * * @param color * 背景颜色 * @return BadgeView */ public BadgeView setBadgeBackgroundColor(int color) { mBgColor = color; mBgPaint.setColor(color); invalidate(); return this; } /** * 设置该控件的背景图形 * * @param shape * 图形 * @return */ public BadgeView setBackgroundShape(int shape) { mBackgroundShape = shape; invalidate(); return this; } /** * 设置该控件的宽 * * @param width * 宽 * @return BadgeView */ public BadgeView setWidth(int width) { this.mWidth = width; this.setBadgeLayoutParams(width, mHeight); return this; } /** * 设置该控件的高 * * @param height * 高 * @return BadgeView */ public BadgeView setHeight(int height) { this.mHeight = height; this.setBadgeLayoutParams(mWidth, height); return this; } /** * 设置该控件的高和宽 * * @param width * 宽 * @param height * 高 * @return */ public BadgeView setBadgeLayoutParams(int width, int height) { this.mWidth = width; this.mHeight = height; FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams(); params.width = dip2px(getContext(), width); params.height = dip2px(getContext(), height); setLayoutParams(params); return this; } /** * 设置该控件的位置 * * @param gravity * 位置 * @return BadgeView */ public BadgeView setBadgeGravity(int gravity) { mGravity = gravity; FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams(); params.gravity = gravity; setLayoutParams(params); return this; } /** * 设置该控件的高和宽、位置 * * @param width * 宽 * @param height * 高 * @param gravity * 位置 * @return BadgeView */ public BadgeView setBadgeLayoutParams(int width, int height, int gravity) { FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams(); params.width = dip2px(getContext(), width); params.height = dip2px(getContext(), height); setLayoutParams(params); setBadgeGravity(gravity); return this; } /** * 设置该控件的文本大小 * * @param size * 文本大小(sp) * @return */ public BadgeView setTextSize(int size) { mTextSize = sp2px(getContext(), size); mTextPaint.setTextSize(sp2px(getContext(), size)); invalidate(); return this; } /** * 设置该控件的文本颜色 * * @param color * 文本颜色 * @return BadgeView */ public BadgeView setTextColor(int color) { mTextColor = color; mTextPaint.setColor(color); invalidate(); return this; } /** * 设置该控件的文本是否为粗体 * * @param flag */ public void setBadgeBoldText(boolean flag) { mTextPaint.setFakeBoldText(flag); invalidate(); } /** * 设置该控件要显示的整数文本 * * @param count * 要显示的整数文本 * @return BadgeView */ public BadgeView setBadgeText(int count) { mText = String.valueOf(count); invalidate(); return this; } /** * 设置该控件要显示的整数文本数字,超过指定上限显示为指定的上限内容 * * @param count * 要显示的整数文本 * @param maxCount * 数字上限 * @param text * 超过上限要显示的字符串文本 * @return BadgeView */ public BadgeView setBadgeText(int count, int maxCount, String text) { if (count <= maxCount) { mText = String.valueOf(count); } else { mText = text; } invalidate(); return this; } /** * 设置该控件要显示的字符串文本 * * @param text * 要显示的字符串文本 * @return BadgeView */ public BadgeView setBadgeText(String text) { mText = text; invalidate(); return this; } /** * 设置绑定的控件 * * @param view * 要绑定的控件 * @return BadgeView */ public BadgeView setBindView(View view) { mIsShow = true; if (getParent() != null) ((ViewGroup) getParent()).removeView(this); if (view == null) return this; if (view.getParent() instanceof FrameLayout) { ((FrameLayout) view.getParent()).addView(this); } else if (view.getParent() instanceof ViewGroup) { ViewGroup parentContainer = (ViewGroup) view.getParent(); int viewIndex = ((ViewGroup) view.getParent()).indexOfChild(view); ((ViewGroup) view.getParent()).removeView(view); FrameLayout container = new FrameLayout(getContext()); ViewGroup.LayoutParams containerParams = view.getLayoutParams(); container.setLayoutParams(containerParams); container.setId(view.getId()); view.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); container.addView(view); container.addView(this); parentContainer.addView(container, viewIndex); } else if (view.getParent() == null) { Log.e(LOG_TAG, "View must have a parent"); } return this; } /** * 设置绑定的控件 * * @param view 要绑定的控件 * @param tabIndex 要绑定的控件的子项 */ public void setBindView(TabWidget view, int tabIndex) { View tabView = view .getChildTabViewAt(tabIndex); this.setBindView(tabView); } /** * 移除绑定的控件 * * @return BadgeView */ public boolean removebindView() { if (getParent() != null) { mIsShow = false; ((ViewGroup) getParent()).removeView(this); return true; } return false; } /** * @return 改控件的显示状态 */ public boolean isShow() { return mIsShow; } /** * @return 控件的字符串文本 */ public String getBadgeText() { return mText; } private int dip2px(Context context, int dip) { return (int) (dip * getContext().getResources().getDisplayMetrics().density + 0.5f); } private int sp2px(Context context, float spValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } }

可自由定制自己喜欢的控件,为了方便使用这里还采用工厂模式封装一些基本方法,如下:

import android.content.Context; import android.view.Gravity; public class BadgeFactory { public static BadgeView create(Context context) { return new BadgeView(context); } public static BadgeView createDot(Context context) { return new BadgeView(context).setBadgeLayoutParams(10, 10) .setTextSize(0) .setBadgeGravity(Gravity.RIGHT | Gravity.TOP) .setBackgroundShape(BadgeView.SHAPE_CIRCLE); } public static BadgeView createCircle(Context context) { return new BadgeView(context).setBadgeLayoutParams(16, 16) .setTextSize(12) .setBadgeGravity(Gravity.RIGHT | Gravity.TOP) .setBackgroundShape(BadgeView.SHAPE_CIRCLE); } public static BadgeView createRectangle(Context context) { return new BadgeView(context).setBadgeLayoutParams(2, 20) .setTextSize(12) .setBadgeGravity(Gravity.RIGHT | Gravity.TOP) .setBackgroundShape(BadgeView.SHAPE_RECTANGLE); } public static BadgeView createOval(Context context) { return new BadgeView(context).setBadgeLayoutParams(25, 20) .setTextSize(12) .setBadgeGravity(Gravity.RIGHT | Gravity.TOP) .setBackgroundShape(BadgeView.SHAPE_OVAL); } public static BadgeView createSquare(Context context) { return new BadgeView(context).setBadgeLayoutParams(20, 20) .setTextSize(12) .setBadgeGravity(Gravity.RIGHT | Gravity.TOP) .setBackgroundShape(BadgeView.SHAPE_SQUARE); } public static BadgeView createRoundRect(Context context) { return new BadgeView(context).setBadgeLayoutParams(25, 20) .setTextSize(12) .setBadgeGravity(Gravity.RIGHT | Gravity.TOP) .setBackgroundShape(BadgeView.SHAPTE_ROUND_RECTANGLE); } }

源码下载:Android实现消息提醒小红点

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-10-10 17:30:43

Android实现消息提醒小红点效果的相关文章

android气泡消息提醒布局

无论是anroid还是ios,气泡消息提醒再正常不过了.然而要定义一个气泡消息提醒确要费一番周折.下面记录下气泡提醒布局. 定义气泡背景shape_unread_message_bg.xml <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android= "http://schemas.android.com/apk/res/android" android:shape=

Android高仿微信5.2.1主界面及消息提醒_Android

好久没更新博客了,最近在做公司的项目,这也算是我接触的第一个正式项目.通过项目的检验,发现自己积累了一年的知识还是远远不够,想要提高,好的方法是 :项目+书+视频+博客.最重要一点:勤动手.最近发现了慕课网的视频,居然都是高清无码免费的!而且满满的干货!我用业余时间跟着视频中大神的讲解学习了不少知识,下面就将这些小demo与大家分享,当然,我做了一些优化,代码与视频中有些出入,但功能可以完全实现. 这是一个模仿5.2.1版本的显示界面,如下图所示: 功能及实现思路简介 主要功能很简单: 1.上面

Android高仿微信5.2.1主界面及消息提醒

好久没更新博客了,最近在做公司的项目,这也算是我接触的第一个正式项目.通过项目的检验,发现自己积累了一年的知识还是远远不够,想要提高,好的方法是 :项目+书+视频+博客.最重要一点:勤动手.最近发现了慕课网的视频,居然都是高清无码免费的!而且满满的干货!我用业余时间跟着视频中大神的讲解学习了不少知识,下面就将这些小demo与大家分享,当然,我做了一些优化,代码与视频中有些出入,但功能可以完全实现. 这是一个模仿5.2.1版本的显示界面,如下图所示: 功能及实现思路简介 主要功能很简单: 1.上面

android ble-第三方应用的微信、LINE消息提醒功能

问题描述 第三方应用的微信.LINE消息提醒功能 现在做一个android蓝牙应用开发,客户要求当手机上有微信消息的时候将消息显示到蓝牙设备上,意思用户不用掏出手机就看到消息了,这个怎么实现?

android的消息通知栏

在android的应用层中,涉及到很多应用框架,例如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架,通知机制,ActionBar框架等等. 下面就来说说经常会使用到通知机制中的通知栏框架(Notificaiton),它适用于交互事件的通知.它是位于顶层可以展开的通知列表.它会时不时的提醒你什么软件该更新了,什么人发你微信消息了等. (网上看了下,全面介绍的文章不多,所以就萌生了写这篇的念头,随便当作回顾笔记.下面我就通过官方文档.源代码

Android后台定时提醒功能实现_Android

前提:考虑到自己每次在敲代码或者打游戏的时候总是会不注意时间,一不留神就对着电脑连续3个小时以上,对眼睛的伤害还是挺大的,重度近视了可是会遗传给将来的孩子的呀,可能老婆都跟别人跑了. 于是,为了保护眼睛,便做了个如下的应用: 打开后效果: 时间到之后有后台提醒: 好了,接下来说一下做这样一个APP主要涉及到的知识点: Service:使用service,便可以在程序即使后台运行的时候,也能够做出相应的提醒,并且不影响手机进行其他工作.AlarmManager:此知识点主要是用来计时,具体的在代码

Android中实现“程序前后台切换效果”和“返回正在运行的程序,而不是一个新Activity”

ANDROID 一.首先是返回正在运行的程序,而不是新的ACTIVITY. 多网上关于 通知栏的例子都是打开一个新的Activity,代码也很多.根据那些代码如下    public void shownotification(String tab)    {        NotificationManager barmanager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);        Notif

Android仿斗鱼直播的弹幕效果_Android

记得之前有位朋友在我的公众号里问过我,像直播的那种弹幕功能该如何实现?如今直播行业确实是非常火爆啊,大大小小的公司都要涉足一下直播的领域,用斗鱼的话来讲,现在就是千播之战.而弹幕则无疑是直播功能当中最为重要的一个功能之一,那么今天,我就带着大家一起来实现一个简单的Android端弹幕效果. 分析 首先我们来看一下斗鱼上的弹幕效果,如下图所示: 这是一个Dota2游戏直播的界面,我们可以看到,在游戏界面的上方有很多的弹幕,看直播的观众们就是在这里进行讨论的. 那么这样的一个界面该如何实现呢?其实并

手机美团消息提醒怎么取消?

1.在你安卓或苹果手机打开并进入到美团软件了. 2.然后如果没有登录我们直接再登录美团账号 然后就会进入到 美团的首页,点击"右下角"的"更多"按钮了,效果如下所示 3.然后在更多的下面你会看到有一项"消息提醒"点一下. 4.在消息提醒界面你会看到有许多的消息和提醒,把后面的两个开关拨一下. 5.后面的开关变灰了美团的消息提醒就设置好了 好了这样设置好了美团这烦人的通知消息就自动给关了,以后再了不会有此消息出现了哦,各位朋友试一下吧.