自定义布局,显示红点功能(类似未读消息数量)

好久没写博客了,最近比较闲,今天无意中看到微信上面的那个《朋友圈》中被点赞时会显示个红点。之前做这种效果时,都是在一个layout中增加一个textView,然后设置背景色为圆形的红色。但是这样写起布局来,一个laout里面会有好几个子view,很是麻烦。所以就在想:如果layout本来就有一个红点,这样用起来是不是就很方便呢?说干就干。

先来几张效果图:

  

功能说明:xml中调用时,支持设置圆点的颜色(不设置默认为红色),支持圆点的位置:左上角、右上角、左下角、右下角,支持设置圆点的大小(半径),支持设置里面文字的字体大小、颜色。

好了,接下来上代码:自定义Layout类:

package buildingblocks.myview.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.RelativeLayout;

import buildingblocks.myview.R;

/**
 * 自带红色点的自定义布局:继承相对布局,可设置红点的位置
 * Created by THINK on 2017/12/12.
 */

public class RedDotLayout extends RelativeLayout {
    //红点里的文本
    private String text = "0";
    //背景颜色:默认为红色
    private int background = Color.RED;
    //圆点的半径:默认为30dp
    private int radius = 30;
    //内容字体的颜色:默认白色
    private int textColor = Color.WHITE;
    //圆点的位置:默认右上角(1:左上角,2:右上角,3:左下角,4:右下角)
    private int location = 2;
    //内容字体大小:默认13sp
    private int textSize = 20;
    //画笔
    private Paint mPaint = new Paint();
    //绘制时控制文本绘制的范围
    private Rect mBound = new Rect();

    public RedDotLayout(Context context) {
        this(context, null);
    }

    public RedDotLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RedDotLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取xml中的自定义样式
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RedDotLayout);
        int n = array.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = array.getIndex(i);
            switch (attr) {
                case R.styleable.RedDotLayout_red_background://背景
                    background = array.getColor(attr, Color.RED);
                    break;
                case R.styleable.RedDotLayout_red_radius://半径
                    radius = array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.RedDotLayout_red_text://内容
                    text = array.getString(attr);
                    break;
                case R.styleable.RedDotLayout_red_textColor://内容字体颜色
                    textColor = array.getColor(attr, Color.WHITE);
                    break;
                case R.styleable.RedDotLayout_red_location://获取圆点的位置
                    location = array.getInteger(attr, 2);
                    break;
                case R.styleable.RedDotLayout_red_textSize://获取内容字体大小
                    textSize = array.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics()));
                    break;
            }
        }
        //释放资源
        array.recycle();
    }

    /**
     * 清除内容:清除内容后会去掉圆点
     */
    public void clear(){
        setText("");
    }
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        if (TextUtils.isEmpty(text)) {
            return;
        }
        //设置画笔抗钜齿
        mPaint.setAntiAlias(true);
        //画背景色
        mPaint.setColor(background);
        int cx = 0;
        int cy = 0;
        switch (location) {
            case 1://左上角
                cx = radius;
                cy = radius;
                break;
            case 2://右上角
                cx = getWidth() - radius;
                cy = radius;
                break;
            case 3://左下角
                cx = radius;
                cy = getHeight() - radius;
                break;
            case 4://右下角
                cx = getWidth() - radius;
                cy = getHeight() - radius;
                break;
        }
        canvas.drawCircle(cx, cy, radius, mPaint);
        mPaint.reset();
        //画内容文字
        //得到绘制文本的范围
        mPaint.setColor(textColor);
        mPaint.setTextSize(textSize);
        mPaint.getTextBounds(text, 0, text.length(), mBound);
        //防止内容太多造成的显示不全
        if (mBound.width() >= radius * 2 || mBound.height() >= radius * 2) {
            text = "...";
        }
        canvas.drawText(text, cx - (mBound.width() / 2), cy + (mBound.height() / 2), mPaint);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    public void setText(String text) {
        this.text = text;
        postInvalidate();
    }
}
styles.xml中的样式:

<resources>

    <!--自带红色圆点的布局样式-->
    <declare-styleable name="RedDotLayout">
        <attr name="red_background" format="color" />
        <attr name="red_radius" format="dimension" />
        <attr name="red_text" format="string" />
        <attr name="red_textColor" format="color" />
        <attr name="red_location" format="integer" />
        <attr name="red_textSize" format="dimension" />
    </declare-styleable>
</resources>
布局文件中直接引用:

<buildingblocks.myview.view.RedDotLayout
    android:id="@+id/redDotLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    custom:red_location="2"
    custom:red_textColor="#f00"
    custom:red_textSize="15sp"
    custom:red_background="#4fd216"
    custom:red_text="99">

    <ImageView
        android:id="@+id/image"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerHorizontal="true"
        android:src="@drawable/d_landelini" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/image"
        android:layout_centerHorizontal="true"
        android:text="好看吗"
        android:textColor="#000000" />

</buildingblocks.myview.view.RedDotLayout>

代码中动态改变数字内容:

 
RedDotLayout redDotLayout;
redDotLayout = (RedDotLayout) findViewById(R.id.redDotLayout);
redDotLayout.setText("199");

备注:布局文件中引用时的属性设置:
custom:red_location="2" //圆点的位置:1:左上角,2:右上角(默认),3:左下角,4:右下角
custom:red_textSize="15sp"//文字的字体大小
custom:red_text="99" //文字内容
custom:red_textColor="#ffffff" //文字内容的字体颜色
custom:red_radius="15dp" //圆点的半径
custom:red_background="#ff0000" //圆点的颜色:默认RED
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值