android自定义提示信息吗,Android自定义未读消息提示View

先上图

5c211e5750f4

未读消息View

介绍

1.可根据文本长度动态改变view的宽度,数字10以下的显示为圆形,10以上的显示为上述效果

2.使用方便,引用到xml中后,直接显示高度即可,即可根据高度自动生成最佳显示效果

3.直接在代码中调用setText()即可

分析

其实完成这样的效果还是很简单的,主要我是通过画一个圆角矩形来实现这样的效果,圆角矩形很轻松就能实现这两种效果的切换,至于怎样子写,之后会有介绍。

关于自适应宽度的实现,我只要是通过重写onMeasure方法,对其进行拦截。

开始实现

实现步骤其实很简单,因为功能上不是很多,对于我现在的需求,只要能显示未读数量并做好适配就好了。所以只要写好onMeasure和onDraw就好了,方法很简单。因为本人实力有限,实现起来肯定还是使用很简单的方法的。

现在我们先看onMeasure,这里主要是是为了做好实现自适应宽度

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//获取控件高度

height = MeasureSpec.getSize(heightMeasureSpec);

//定义字体大小,自测了一下,与高度相差6dp的字体大小看着还是挺舒服的

textSize = height - getResources().getDimensionPixelSize(R.dimen.dp6);

textPaint.setTextSize(textSize);

//获取文本宽度

int textWidth = (int) textPaint.measureText(text);

//区分画圆的是圆形还是圆角矩形

if (text.length() > 1) {

roundWidth = textWidth + height - textWidth / text.length();

} else {

roundWidth = height;

}

//重新测量控件

setMeasuredDimension(roundWidth, height);

}

上述方法还是很简单的也标号注释了,不用一句句来讲了。

roundWidth = textWidth + height - textWidth / text.length();实现上述效果的核心就是这段代码,我想应该看得懂的。逻辑不是很强。

现在我们再看onDraw,也是最后一步画矩形与画字

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//画矩形

canvas.setDrawFilter(paintFlagsDrawFilter);

roundRectF.set(0, 0, roundWidth, height);

canvas.drawRoundRect(roundRectF, height / 2, height / 2, roundRectPaint);

//画字

Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();

float top = fontMetrics.top;

float bottom = fontMetrics.bottom;

int baseLintY = (int) (roundRectF.centerY() - top / 2 - bottom / 2);

canvas.drawText(text, roundRectF.centerX(), baseLintY, textPaint);

}

对于画矩形和画字不是这篇的重点,不懂的可以自己百度一下,我也是百度慢慢学起来的。主要是画字需要居中,关键在于int baseLintY = (int) (roundRectF.centerY() - top / 2 - bottom / 2);这边代码,获取字体的基线,来实现居中效果。

最后上所有代码,不是很难,代码量也不多,很容易懂

package com.demo.view;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.PaintFlagsDrawFilter;

import android.graphics.RectF;

import android.support.annotation.Nullable;

import android.util.AttributeSet;

import android.view.View;

import com.demo.R;

public class MyTextView extends View {

private Paint roundRectPaint;

private RectF roundRectF;

private int height;

private int roundWidth;

private Paint textPaint;

private float textSize;

private String text;

private PaintFlagsDrawFilter paintFlagsDrawFilter;

public MyTextView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs, 0);

}

public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initView();

}

private void initView() {

text = "2";

roundRectPaint = new Paint();

roundRectPaint.setStyle(Paint.Style.FILL);

roundRectPaint.setAntiAlias(true);

roundRectPaint.setColor(Color.RED);

roundRectF = new RectF();

//设置字体为粗体

textPaint = new Paint(Paint.LINEAR_TEXT_FLAG);

textPaint.setColor(Color.WHITE);

textPaint.setAntiAlias(true);

textPaint.setTextAlign(Paint.Align.CENTER);

//实现抗锯齿

paintFlagsDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//获取控件高度

height = MeasureSpec.getSize(heightMeasureSpec);

//定义字体大小,自测了一下,与高度相差6dp的字体大小看着还是挺舒服的

textSize = height - getResources().getDimensionPixelSize(R.dimen.dp6);

textPaint.setTextSize(textSize);

//获取文本宽度

int textWidth = (int) textPaint.measureText(text);

//区分画圆的是圆形还是圆角矩形

if (text.length() > 1) {

roundWidth = textWidth + height - textWidth / text.length();

} else {

roundWidth = height;

}

//重新测量控件

setMeasuredDimension(roundWidth, height);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//画矩形

canvas.setDrawFilter(paintFlagsDrawFilter);

roundRectF.set(0, 0, roundWidth, height);

canvas.drawRoundRect(roundRectF, height / 2, height / 2, roundRectPaint);

//画字

Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();

float top = fontMetrics.top;

float bottom = fontMetrics.bottom;

int baseLintY = (int) (roundRectF.centerY() - top / 2 - bottom / 2);

canvas.drawText(text, roundRectF.centerX(), baseLintY, textPaint);

}

public void setText(String text) {

this.text = text;

//重走onMeasure

requestLayout();

}

}

代码真的很少,看不懂的查一下也很快能看懂的。

最后在xml中

android:layout_marginTop="20dp"

android:layout_marginLeft="20dp"

android:layout_width="wrap_content"

android:layout_height="30dp"/>

好了,就这样结束了,这里android:layout_width不管设什么值都是自适应的,因为在onMeasure中直接定死了。若要区分开来,可重写onMeasure做判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值