搜索
您的当前位置:首页Android实现消息提醒小红点效果

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

时间:2020-04-27 来源:乌哈旅游
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); } }

源码下载:

以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top