本人分享一下,自己写的一个消息提醒小红点控件,支持圆、矩形、椭圆、圆角矩形、正方形五种图形样式,可带文字,支持链式操作。
先看一下实现效果,随便测了几个控件(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; } } public BadgeView setBadgeBackgroundColor(int color) { mBgColor = color; mBgPaint.setColor(color); invalidate(); return this; } public BadgeView setBackgroundShape(int shape) { mBackgroundShape = shape; invalidate(); return this; } public BadgeView setWidth(int width) { this.mWidth = width; this.setBadgeLayoutParams(width, mHeight); return this; } public BadgeView setHeight(int height) { this.mHeight = height; this.setBadgeLayoutParams(mWidth, height); return this; } 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; } public BadgeView setBadgeGravity(int gravity) { mGravity = gravity; FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams(); params.gravity = gravity; setLayoutParams(params); return this; } 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; } public BadgeView setTextSize(int size) { mTextSize = sp2px(getContext(), size); mTextPaint.setTextSize(sp2px(getContext(), size)); invalidate(); return this; } public BadgeView setTextColor(int color) { mTextColor = color; mTextPaint.setColor(color); invalidate(); return this; } public void setBadgeBoldText(boolean flag) { mTextPaint.setFakeBoldText(flag); invalidate(); } public BadgeView setBadgeText(int count) { mText = String.valueOf(count); invalidate(); return this; } public BadgeView setBadgeText(int count, int maxCount, String text) { if (count <= maxCount) { mText = String.valueOf(count); } else { mText = text; } invalidate(); return this; } public BadgeView setBadgeText(String text) { mText = text; invalidate(); return this; } 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; } public void setBindView(TabWidget view, int tabIndex) { View tabView = view .getChildTabViewAt(tabIndex); this.setBindView(tabView); } public boolean removebindView() { if (getParent() != null) { mIsShow = false; ((ViewGroup) getParent()).removeView(this); return true; } return false; } public boolean isShow() { return mIsShow; } 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); } }
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1142
183.71 KB下载数642
644.84 KB下载数2755
相关文章
发现更多好内容猜你喜欢
AI推送时光机Android实现消息提醒小红点效果
后端开发2023-05-30
Android实现未读消息小红点显示实例
后端开发2024-04-02
Android怎么实现未读消息小红点显示
后端开发2023-06-29
Android利用Badge组件实现未读消息小红点
后端开发2023-01-14
前端与RabbitMQ实时消息推送未读消息小红点实现示例
后端开发2024-04-02
Android ViewPager导航小圆点实现无限循环效果
后端开发2023-05-30
Android开发中使用 BadgeView实现一个红点更新信息提示功能
后端开发2023-05-31
Android如何实现通知消息水平播放、无限循环效果
后端开发2023-05-30
Android实现手势滑动多点触摸放大缩小图片效果
后端开发2022-06-06
咦!没有更多了?去看看其它编程学习网 内容吧