Android自定义未读消息提示View

微信的小红点不知道逼死了多少人的强迫症,今天我们就来实现一个带有小红点的View,先上效果图:

这里写图片描述

这里写图片描述

读者须知:

虽然我会在文末给出源码,但是我的源码只是按照我的需求编写的,希望读者能够理解整个思路然后结合自己的实际需求编写自己需要的代码,其实这个View并不难,踏实下来,多花点时间一定能看懂。

思路

这个未读消息提示View总共包含三个部分,头像部分(可以看成一个正方形),圆圈部分(就是红色的部分),文字部分(里面会标明消息的数量,如果大于99就显示“99+”,如果为0那么就不显示圆圈部分和文字部分),注意文字部分是在圆圈部分里面,所以文字不能超过圆圈部分的边界

让我们通过一张图看懂整个布局:

这里写图片描述

1 整个View包括圆和正方形,所以宽度和高度为4而不是OA

2 我的情况是把圆心放在了正方形的顶点处,如果你们靠近正方形或者远离正方形可以自己新建坐标轴

3 圆和正方形(或者说是Bitmap)都好画但是如果文字画出来要是超过了圆的范围该怎么办呢?可以缩小文字的textSize或者增加圆的长度(我是采用了后者)

源码仅供参考:

package com.test.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.test.R;

/**
 * @Description: 仿微信未读消息View
 * @Author: Liangchaojie
 * @Create On 2017/12/14 10:22
 */

public class MessageView extends View{

    private Paint mPiant=null;
    private Paint mTextPiant=null;//画文字的笔
    private int rate=6;//圆和正方形的比例
    private int square_color;//正方形的颜色
    private int circle_color;
    private int text_color;
    private boolean isShow;//是否显示圆圈消息
    private String text;
    public MessageView(Context context) {
        this(context,null);
    }

    public MessageView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MessageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
    public synchronized void setText(String text) {
        this.text = text;
        init();
        invalidate();
    }
    public synchronized void setShow(boolean show) {
        isShow = show;
        init();
        invalidate();
    }
    private void init() {
        mPiant = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPiant = new Paint(Paint.ANTI_ALIAS_FLAG);
        square_color = getResources().getColor(R.color.yellow);
        circle_color = getResources().getColor(R.color.red);
        text_color = getResources().getColor(R.color.white);
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int w = Math.min(getWidth(),getHeight());
        int h = Math.min(getWidth(),getHeight());

        //获取文字的宽度和高度
        Rect rect1=new Rect();
        mTextPiant.setColor(text_color);
        mTextPiant.setTextSize(30);
        mTextPiant.setFakeBoldText(true);
        mTextPiant.getTextBounds(text,0,text.length(),rect1);

        //获取指定图片
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.ion);

        //已知图片的尺寸,根据比例获取圆的半径
        int r = bitmap.getWidth() / rate;//圆的半径
        int c = bitmap.getWidth();//正方形周长

        //判断文字和圆的半径的大小关系,如果文字长度比圆半径大,那么就需要改变圆的半径
        int x_diff = rect1.centerX() -  r;
        int y_diff = rect1.centerY() -  r;
        if(x_diff>0||y_diff>0){
            r = (int) Math.sqrt(rect1.centerX()*rect1.centerX()+rect1.centerY()*rect1.centerY());
        }

        //画图形
        canvas.drawBitmap(bitmap,0,r,mPiant);

        if(isShow){//如果需要展示图标
            drawCircle(canvas, r, c);//画圆圈
            drawText(canvas, r, c,rect1);//画文本
        }
    }


    private void drawText(Canvas canvas,int r, int c,Rect rect1) {
        int x = c-rect1.centerX();
        int y = r - rect1.centerY();
        canvas.drawText(text,x,y, mTextPiant);
    }

    private void drawCircle(Canvas canvas, int r, int c) {
        mPiant.setColor(circle_color);
        canvas.drawCircle(c,r,r,mPiant);
    }


}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值