婚恋交友系统源码,实现带有边框的文本

实际的婚恋交友系统源码中我们经常会遇到边框的问题,一开始我都是直接用shape来实现,但是这种方式非常的麻烦,后面又用了三方库SuperTextView,后面学习了自定义View自己来实现一下吧.

Code

public class BorderTextView extends AppCompatTextView {

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

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

    public BorderTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    /**
     * @param borderColor  border颜色
     * @param borderWidths border 宽度
     * @param borderRadius border 圆角半径
     */
    public void setBorder(final int borderColor, final int[] borderWidths, final int[] borderRadius) {
        setTextColor(borderColor);
        Drawable drawable = new GradientDrawable() {
            @Override
            public void draw(Canvas canvas) {
                super.draw(canvas);
                drawBorder(canvas, borderColor, borderWidths, borderRadius);
            }
        };
        setBackground(drawable);
    }

    /**
     * 绘制border
     */
    private void drawBorder(Canvas canvas, final int borderColor, final int[] borderWidths, final int[] borderRadius) {
        //获取当前canvas的宽高
        Rect rect = canvas.getClipBounds();
        final int width = rect.width();
        final int height = rect.height();

        int borderWidthLeft;
        int borderWidthTop;
        int borderWidthRight;
        int borderWidthBottom;

        //取得我们的边框宽度,并附加给相应变量
        if (borderWidths != null && borderWidths.length == 4) {
            borderWidthLeft = Math.min(width / 2, borderWidths[0]);
            borderWidthTop = Math.min(height / 2, borderWidths[1]);
            borderWidthRight = Math.min(width / 2, borderWidths[2]);
            borderWidthBottom = Math.min(height / 2, borderWidths[3]);
        } else {
            return;
        }

        // 设置画笔
        Paint paint = new Paint();
        //抗锯齿
        paint.setAntiAlias(true);
        //画笔颜色
        paint.setColor(borderColor);
        //画笔样式
        paint.setStyle(Paint.Style.STROKE);
        //设置边框宽度
        paint.setStrokeWidth(borderWidthLeft);

        // 判断当前边框是否相等
        if ((borderWidthLeft == borderWidthTop) && (borderWidthLeft == borderWidthRight) && (borderWidthLeft == borderWidthBottom)) {
            if (borderWidthLeft == 0) {
                return;
            }
            // borderRadius != null且borderWidth!-0;计算并画出圆角边框,否则为直角边框
            if (borderRadius != null && borderRadius.length == 4) {
                int sum = 0;
                /**
                 * 循环传递的最后一个参数,相加
                 * 是数组的原因是适应更多的边框需求,因为你不一定四个边框都是一个圆角度数
                 */
                for (int i = 0; i < borderRadius.length; i++) {
                    if (borderRadius[i] < 0) {
                        return;
                    }
                    sum += borderRadius[i];
                }
                //如果传递的都是0直接绘制即可
                if (sum == 0) {
                    canvas.drawRect(rect, paint);
                }
                int borderWidth = borderWidthLeft;

                int mMaxRadiusX = width / 2 - borderWidth / 2;
                int mMaxRadiusY = height / 2 - borderWidth / 2;

                int topLeftRadiusX = Math.min(mMaxRadiusX, borderRadius[0]);
                int topLeftRadiusY = Math.min(mMaxRadiusY, borderRadius[0]);
                int topRightRadiusX = Math.min(mMaxRadiusX, borderRadius[1]);
                int topRightRadiusY = Math.min(mMaxRadiusY, borderRadius[1]);
                int bottomRightRadiusX = Math.min(mMaxRadiusX, borderRadius[2]);
                int bottomRightRadiusY = Math.min(mMaxRadiusY, borderRadius[2]);
                int bottomLeftRadiusX = Math.min(mMaxRadiusX, borderRadius[3]);
                int bottomLeftRadiusY = Math.min(mMaxRadiusY, borderRadius[3]);

                //绘制左上圆角,通过旋转来达到圆角的效果,本质上其实绘制的是圆弧
                if (topLeftRadiusX < borderWidth || topLeftRadiusY < borderWidth) {

                    RectF arc1 = new RectF(0, 0, topLeftRadiusX * 2, topLeftRadiusY * 2);
                    paint.setStyle(Paint.Style.FILL);
                    canvas.drawArc(arc1, 180, 90, true, paint);
                } else {
                    RectF arc1 = new RectF(borderWidth / 2, borderWidth / 2, topLeftRadiusX * 2 - borderWidth / 2, topLeftRadiusY * 2 - borderWidth / 2);
                    paint.setStyle(Paint.Style.STROKE);
                    canvas.drawArc(arc1, 180, 90, false, paint);
                }
                //绘制上方的边框
                canvas.drawLine(topLeftRadiusX, borderWidth / 2, width - topRightRadiusX, borderWidth / 2, paint);

                //绘制右上圆角
                if (topRightRadiusX < borderWidth || topRightRadiusY < borderWidth) {
                    RectF arc2 = new RectF(width - topRightRadiusX * 2, 0, width, topRightRadiusY * 2);
                    paint.setStyle(Paint.Style.FILL);
                    canvas.drawArc(arc2, 270, 90, true, paint);
                } else {
                    RectF arc2 = new RectF(width - topRightRadiusX * 2 + borderWidth / 2, borderWidth / 2, width - borderWidth / 2, topRightRadiusY * 2 - borderWidth / 2);
                    paint.setStyle(Paint.Style.STROKE);
                    canvas.drawArc(arc2, 270, 90, false, paint);
                }
                //绘制右边边框
                canvas.drawLine(width - borderWidth / 2, topRightRadiusY, width - borderWidth / 2, height - bottomRightRadiusY, paint);
                //绘制右下圆角
                if (bottomRightRadiusX < borderWidth || bottomRightRadiusY < borderWidth) {
                    RectF arc3 = new RectF(width - bottomRightRadiusX * 2, height - bottomRightRadiusY * 2, width, height);
                    paint.setStyle(Paint.Style.FILL);
                    canvas.drawArc(arc3, 0, 90, true, paint);
                } else {
                    RectF arc3 = new RectF(width - bottomRightRadiusX * 2 + borderWidth / 2, height - bottomRightRadiusY * 2 + borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2);
                    paint.setStyle(Paint.Style.STROKE);
                    canvas.drawArc(arc3, 0, 90, false, paint);
                }
                //绘制底部边框
                canvas.drawLine(bottomLeftRadiusX, height - borderWidth / 2, width - bottomRightRadiusX, height - borderWidth / 2, paint);
                //绘制左下圆角
                if (bottomLeftRadiusX < borderWidth || bottomLeftRadiusY < borderWidth) {
                    RectF arc4 = new RectF(0, height - bottomLeftRadiusY * 2, bottomLeftRadiusX * 2, height);
                    paint.setStyle(Paint.Style.FILL);
                    canvas.drawArc(arc4, 90, 90, true, paint);
                } else {
                    RectF arc4 = new RectF(borderWidth / 2, height - bottomLeftRadiusY * 2 + borderWidth / 2, bottomLeftRadiusX * 2 - borderWidth / 2, height - borderWidth / 2);
                    paint.setStyle(Paint.Style.STROKE);
                    canvas.drawArc(arc4, 90, 90, false, paint);
                }
                //绘制左边边框
                canvas.drawLine(borderWidth / 2, topLeftRadiusY, borderWidth / 2, height - bottomLeftRadiusY, paint);
            } else {
                //如果没有传递圆角的参数,直接绘制即可
                canvas.drawRect(rect, paint);
            }
        } else {
            //当边框的宽度不同时,绘制不同的线粗,通过borderWidthLeft,rect.top,rect.bottom来确定每根线所在的位置
            if (borderWidthLeft > 0) {
                paint.setStrokeWidth(borderWidthLeft);
                canvas.drawLine(borderWidthLeft / 2, rect.top, borderWidthLeft / 2, rect.bottom, paint);
            }
            if (borderWidthTop > 0) {
                paint.setStrokeWidth(borderWidthTop);
                canvas.drawLine(rect.left, borderWidthTop / 2, rect.right, borderWidthTop / 2, paint);
            }
            if (borderWidthRight > 0) {
                paint.setStrokeWidth(borderWidthRight);
                canvas.drawLine(rect.right - borderWidthRight / 2, rect.top, rect.right - borderWidthRight / 2, rect.bottom, paint);
            }
            if (borderWidthBottom > 0) {
                paint.setStrokeWidth(borderWidthBottom);
                canvas.drawLine(rect.left, rect.bottom - borderWidthBottom / 2, width, rect.bottom - borderWidthBottom / 2, paint);
            }
        }
    }
}

效果

image.png

相应代码里都有注释,代码本质是通过绘制四根线来实现边框的效果,通过我们传递的两个参数,一个是边框宽度,利用数组,拥有更强的扩展性,可以设置四个方向的线粗.第二个是圆角度数,顺序分别是左上,右上,右下,左下.

当我们的圆角有参数时,线的宽度是有改变的,会稍微短一点,留给矩形控件,防止过度绘制.

Drawable drawable = new GradientDrawable() {
    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        drawBorder(canvas, borderColor, borderWidths, borderRadius);
    }
};

这一部分婚恋交友系统源码代码你也可以使用BitmapDrawable,不过编译器会提示过时,问题不大,也能运行.

这种婚恋交友系统源码代码我不知道该怎么解释,相应的RectF,canvas的构造方法我都介绍吐了,都是一个样子,只不过计算宽高很复杂而已,总之思路就向上面说的一样.
声明:本文由云豹科技转发自只是未遇见博客,如有侵权请联系作者删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值