android消息提示方法自定义,Android自定义消息提示容器

本文详细介绍了如何通过自定义`CustomMessageHintContainerView`实现消息提示容器的绘制,包括dispatchDraw方法的应用、背景高度计算、自适应逻辑以及关键属性设置。通过实例展示了如何根据自定义属性调整提示文字位置、颜色和大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9d34b8370034

自定义消息提示容器.png

效果

9d34b8370034

效果图

实现逻辑

知识点

1、dispatchDraw(Canvas canvas)绘制子View,在这里绘制可以保证在其子View的上层

2、TextPaint默认从底部开始绘制文字,setTextAlign()可以设置绘制文本的对齐方式

实现思路

1、确认绘制背景的高度,因为不管是否开启自适应,高度始终不变。代码里体现在countDefaultTextBackgroundSize()中

2、根据自定义属性,确定绘制区域。代码里体现在countHintTextPosition()中

3、位置确定着手开始绘制背景和数字。dispatchDraw()

源码

/**

* 自定义消息提示容器

* {@link #countHintTextPosition() 计算绘制位置}

* {@link #countDefaultTextBackgroundSize() 计算背景高度}

*

* @attr customHintTextColor //消息数字颜色

* @attr customHintTextSize //消息数字尺寸

* @attr customHintTextBackground //消息背景颜色

* @attr customSelfAdaption //背景是否自适应数字大小

* @attr customHintTextMarginLeft //距离容器左侧外边距

* @attr customHintTextMarginRight //距离容器右侧外边距

* @attr customHintTextMarginTop //距离容器顶部外边距

* @attr customHintTextMarginBottom //距离容器底部外边距

* @attr customHintPosition //消息提示相对容器位置

*/

public class CustomMessageHintContainerView extends LinearLayout {

private static final String TAG = "CustomMessageHintContai";

//提示文字默认长度

private final int DEFAULT_LENGTH = 3;

//左上

public static final int POSITION_TOP_LIFT = 101;

//左下

public static final int POSITION_BOTTOM_LIFT = 102;

//右上

public static final int POSITION_TOP_RIGHT = 103;

//右下

public static final int POSITION_BOTTOM_RIGHT = 104;

/**

* 提示文字内容

*/

private String mMessageHintTextContent;

//绘制提示文字背景的画笔

private Paint mPaint;

//绘制提示文字的画笔

private TextPaint mTextPaint;

//提示文字的颜色

private int mMessageHintTextColor;

//提示文字的尺寸

private float mMessageHintTextSize;

//提示文字的背景颜色

private int mMessageHintBackgroundColor;

//提示内容相对容器的位置

private int mMessageHintPosition;

//是否根据文字自适应背景大小

private boolean isSelfAdaption;

//提示文字外边距

private float mMessageHintMarginLeft;

private float mMessageHintMarginTop;

private float mMessageHintMarginRight;

private float mMessageHintMarginBottom;

//默认背景的高度

private float mDefaultBackgroundHeight = 0;

public CustomMessageHintContainerView(Context context) {

this(context, null);

}

public CustomMessageHintContainerView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public CustomMessageHintContainerView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

//初始默认属性

initDefaultAttrs();

//初始自定义属性

initAttrs(context, attrs);

//初始画笔

initPaint();

//计算默认情况下需要的背景尺寸

countDefaultTextBackgroundSize();

}

@Override

protected void dispatchDraw(Canvas canvas) {

super.dispatchDraw(canvas);

RectF mRectF = countHintTextPosition();

if (mRectF != null) {

float backgroundWidth = mRectF.width();

float backgroundHeight = mRectF.height();

float radius = backgroundHeight / 2.0F;

//绘制背景

canvas.drawRoundRect(mRectF, radius, radius, mPaint);

Rect measureTextSize = measureTextSize("8");

//绘制文字

if (!isSelfAdaption) {

if (Integer.parseInt(mMessageHintTextContent) > 99) {

canvas.drawText("99+", backgroundWidth / 2.0F + mRectF.left, radius + mRectF.top + measureTextSize.height() / 2.0F, mTextPaint);

} else {

canvas.drawText(mMessageHintTextContent, backgroundWidth / 2.0F + mRectF.left, radius + mRectF.top + measureTextSize.height() / 2.0F, mTextPaint);

}

} else {

canvas.drawText(mMessageHintTextContent, backgroundWidth / 2.0F + mRectF.left, radius + mRectF.top + measureTextSize.height() / 2.0F, mTextPaint);

}

}

}

/**

* 计算默认背景尺寸

*/

private void countDefaultTextBackgroundSize() {

if (!TextUtils.isEmpty(mMessageHintTextContent)) {

StringBuffer mStringBuffer = new StringBuffer();

for (int i = 0; i < DEFAULT_LENGTH; i++) {

mStringBuffer.append("8");

}

Rect mDefaultTextRect = measureTextSize(mStringBuffer.toString());

mDefaultBackgroundHeight = (float) Math.ceil(Math.sqrt((Math.pow(mDefaultTextRect.width(), 2) + Math.pow(mDefaultTextRect.height(), 2))));

}

}

/**

* 计算提示文字显示位置

*/

private RectF countHintTextPosition() {

RectF mRectF = null;

if (!TextUtils.isEmpty(mMessageHintTextContent)) {

if (mDefaultBackgroundHeight == 0) {

countDefaultTextBackgroundSize();

}

//显示内容的文字尺寸

Rect mTextContentRect = measureTextSize(mMessageHintTextContent);

int mMeasuredWidth = this.getMeasuredWidth();

int mMeasuredHeight = this.getMeasuredHeight();

mRectF = new RectF();

switch (mMessageHintPosition) {

case POSITION_TOP_LIFT:

mRectF.top = mMessageHintMarginTop;

mRectF.bottom = mMessageHintMarginTop + mDefaultBackgroundHeight;

mRectF.left = mMessageHintMarginLeft;

if (isSelfAdaption) {

if (mMessageHintTextContent.length() <= DEFAULT_LENGTH) {

mRectF.right = mMessageHintMarginLeft + mDefaultBackgroundHeight;

} else {

mRectF.right = mMessageHintMarginLeft + mTextContentRect.width() + mDefaultBackgroundHeight / 2;

}

} else {

mRectF.right = mMessageHintMarginLeft + mDefaultBackgroundHeight;

}

break;

case POSITION_BOTTOM_LIFT:

mRectF.left = mMessageHintMarginLeft;

mRectF.bottom = mMeasuredHeight - mMessageHintMarginBottom;

mRectF.top = mMeasuredHeight - mMessageHintMarginBottom - mDefaultBackgroundHeight;

if (isSelfAdaption) {

if (mMessageHintTextContent.length() <= DEFAULT_LENGTH) {

mRectF.right = mMessageHintMarginLeft + mDefaultBackgroundHeight;

} else {

mRectF.right = mMessageHintMarginLeft + mTextContentRect.width() + mDefaultBackgroundHeight / 2;

}

} else {

mRectF.right = mMessageHintMarginLeft + mDefaultBackgroundHeight;

}

break;

case POSITION_TOP_RIGHT:

mRectF.top = mMessageHintMarginTop;

mRectF.bottom = mMessageHintMarginTop + mDefaultBackgroundHeight;

mRectF.right = mMeasuredWidth - mMessageHintMarginRight;

if (isSelfAdaption) {

if (mMessageHintTextContent.length() <= DEFAULT_LENGTH) {

mRectF.left = mMeasuredWidth - (mMessageHintMarginRight + mDefaultBackgroundHeight);

} else {

mRectF.left = mMeasuredWidth - (mMessageHintMarginRight + mTextContentRect.width() + mDefaultBackgroundHeight / 2);

}

} else {

mRectF.left = mMeasuredWidth - (mMessageHintMarginRight + mDefaultBackgroundHeight);

}

break;

case POSITION_BOTTOM_RIGHT:

mRectF.right = mMeasuredWidth - mMessageHintMarginRight;

mRectF.bottom = mMeasuredHeight - mMessageHintMarginBottom;

mRectF.top = mMeasuredHeight - mMessageHintMarginBottom - mDefaultBackgroundHeight;

if (isSelfAdaption) {

if (mMessageHintTextContent.length() <= DEFAULT_LENGTH) {

mRectF.left = mMeasuredWidth - mMessageHintMarginRight - mDefaultBackgroundHeight;

} else {

mRectF.left = mMeasuredWidth - mMessageHintMarginRight - mTextContentRect.width() - mDefaultBackgroundHeight / 2;

}

} else {

mRectF.left = mMeasuredWidth - mMessageHintMarginRight - mDefaultBackgroundHeight;

}

break;

default:

mRectF.top = mMessageHintMarginTop;

mRectF.bottom = mMessageHintMarginTop + mDefaultBackgroundHeight;

mRectF.right = mMeasuredWidth - mMessageHintMarginRight;

if (isSelfAdaption) {

if (mMessageHintTextContent.length() <= DEFAULT_LENGTH) {

mRectF.left = mMeasuredWidth - (mMessageHintMarginRight + mDefaultBackgroundHeight);

} else {

mRectF.left = mMeasuredWidth - (mMessageHintMarginRight + mTextContentRect.width() + mDefaultBackgroundHeight / 2);

}

} else {

mRectF.left = mMeasuredWidth - (mMessageHintMarginRight + mDefaultBackgroundHeight);

}

}

}

return mRectF;

}

//初始化画笔

private void initPaint() {

//绘制背景画笔

mPaint = new Paint();

mPaint.setAntiAlias(true);

mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

mPaint.setColor(mMessageHintBackgroundColor);

//绘制文字画笔

mTextPaint = new TextPaint();

mTextPaint.setAntiAlias(true);

mTextPaint.setColor(mMessageHintTextColor);

mTextPaint.setTextSize(mMessageHintTextSize);

mTextPaint.setTextAlign(TextPaint.Align.CENTER);

}

/**

* 初始默认属性

*/

private void initDefaultAttrs() {

//默认文字颜色为白色

mMessageHintTextColor = Color.WHITE;

//默认文字大小12SP

mMessageHintTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, getResources().getDisplayMetrics());

//默认提示文字背景颜色红色

mMessageHintBackgroundColor = Color.RED;

//默认提示文字位置在右上角

mMessageHintPosition = POSITION_TOP_RIGHT;

//默认开启文字自适应

isSelfAdaption = true;

//默认外边距

mMessageHintMarginLeft = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics());

mMessageHintMarginRight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics());

mMessageHintMarginTop = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics());

mMessageHintMarginBottom = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics());

}

/**

* 初始化自定义属性

*/

private void initAttrs(Context context, AttributeSet attrs) {

TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomMessageHintContainerView);

isSelfAdaption = mTypedArray.getBoolean(R.styleable.CustomMessageHintContainerView_customSelfAdaption, isSelfAdaption);

mMessageHintBackgroundColor = mTypedArray.getColor(R.styleable.CustomMessageHintContainerView_customHintTextBackground, mMessageHintBackgroundColor);

mMessageHintTextColor = mTypedArray.getColor(R.styleable.CustomMessageHintContainerView_customHintTextColor, mMessageHintTextColor);

mMessageHintTextSize = mTypedArray.getDimension(R.styleable.CustomMessageHintContainerView_customHintTextSize, mMessageHintTextSize);

mMessageHintPosition = mTypedArray.getInt(R.styleable.CustomMessageHintContainerView_customHintPosition, mMessageHintPosition);

mMessageHintMarginLeft = mTypedArray.getDimension(R.styleable.CustomMessageHintContainerView_customHintTextMarginLeft, mMessageHintMarginLeft);

mMessageHintMarginRight = mTypedArray.getDimension(R.styleable.CustomMessageHintContainerView_customHintTextMarginRight, mMessageHintMarginRight);

mMessageHintMarginTop = mTypedArray.getDimension(R.styleable.CustomMessageHintContainerView_customHintTextMarginTop, mMessageHintMarginTop);

mMessageHintMarginBottom = mTypedArray.getDimension(R.styleable.CustomMessageHintContainerView_customHintTextMarginBottom, mMessageHintMarginBottom);

mTypedArray.recycle();

}

/**

* 测量文字的尺寸

*

* @return 一个汉字的矩阵

*/

private Rect measureTextSize(String content) {

Rect mRect = null;

if (!TextUtils.isEmpty(content)) {

if (mTextPaint != null) {

mRect = new Rect();

mTextPaint.getTextBounds(content, 0, content.length(), mRect);

}

}

return mRect;

}

/**

* 设置提示消息数

*

* @param number 提示数

*/

public void setMessageNumber(int number) {

this.mMessageHintTextContent = String.valueOf(number);

invalidate();

}

/**

* 设置背景根据内容自适应

*

* @param isSelfAdaption 是否开启自适应

*/

public void setSelfAdaption(boolean isSelfAdaption) {

this.isSelfAdaption = isSelfAdaption;

invalidate();

}

/**

* 设置消息相对容器的位置

*

* @param messageHintPosition 位置

*

See

* {@link #POSITION_TOP_RIGHT 右上角},

* {@link #POSITION_BOTTOM_LIFT 左下角},

* {@link #POSITION_BOTTOM_RIGHT 右下角},

* {@link #POSITION_TOP_LIFT 左上角}

*/

public void setMessageHintPosition(int messageHintPosition) {

this.mMessageHintPosition = messageHintPosition;

invalidate();

}

/**

* 获取提示消息数

*

* @return 消息数

*/

public int getMessageHintCount() {

if (TextUtils.isEmpty(mMessageHintTextContent)) {

return 0;

}

return Integer.parseInt(mMessageHintTextContent);

}

/**

* 获取自适应状态

*

* @return 状态

*/

public boolean getSelfAdaptionStatus() {

return isSelfAdaption;

}

}

自定义属性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值