Android 一行显示全部内容的TextView--SingleLineTextView

写在前面的话

奇葩的需求造就奇葩代码!

需求是这样的:将描述信息只显示一行,而且内容要全部显示。一般这样的描述信息显示不了后面就直接写省略号,用TextView的属性直接可以搞定。如果一定要达到需求所说的那样,那只能将文本的字体缩小,如是程序员开始埋头写代码!

步骤

(1)获取文本的长度,textWidth;
(2)获取显示区域的长度,areaWidth;
(3)比较textWidth和areaWidth,如果textWidth>areaWidth,就缩小字体,直到textWidth<=areaWidth刚好显示字体为止。

实现

1.在values目录下创建attrs.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="SingleLineTextView">
        <attr name="textContent" format="string"></attr>
        <attr name="textSize" format="dimension"></attr>
        <attr name="textColor" format="color"></attr>
    </declare-styleable>
</resources>

2.创建SingleLineTextView继承自TextView,在构造方法中利用TypedArray获取相应值:

    public SingleLineTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray ta = context.obtainStyledAttributes(attrs,
                R.styleable.SingleLineTextView, defStyle, 0);

        //获取文本
        textContent = ta.getString(R.styleable.SingleLineTextView_textContent);
        //字体大小
        textSize = ta.getDimensionPixelSize(R.styleable.SingleLineTextView_textSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
        //字体颜色
        textColor = ta.getColor(R.styleable.SingleLineTextView_textColor, Color.BLACK);

        ta.recycle();

        //初始化画笔
        initPaint();
    }

3.利用画笔Paint,获取文本的长度:

    //初始化画笔
    private void initPaint() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(textSize);
        paint.setColor(textColor);

        //获取文本的宽度
        textWidth = paint.measureText(textContent);
        //文本的高度
        textHeight = paint.descent() - paint.ascent();
    }

4.重写onMeasure()方法:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int widthsize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int width;
        int height;

        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthsize;
        } else {
            width = getPaddingLeft() + (int)(textWidth+0.5) + getPaddingRight();
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            height = getPaddingTop() + (int)(textHeight+0.5) + getPaddingBottom();
        }

        setMeasuredDimension(width, height);
    }

onMeasure()方法的实现是一个常规写法,也可以说是一个固定写法,根据长宽的模式,确定长度和宽度。徐宜生的《Android群英传》里面讲这个很详细!以后可能会写一篇这方面的总结!

5.重写onDraw()方法:

    @Override
    protected void onDraw(Canvas canvas) {

        //如果文本的宽度大于显示的宽度,将字体大小减小
        while (textWidth > getWidth()) {
            paint.setTextSize(textSize--);
            textWidth = paint.measureText(textContent);
        }

        //让文本居中显示, 画出文本
        float textBaseline = (getHeight() - (paint.descent() + paint.ascent())) / 2.0f;
        canvas.drawText(textContent, (getWidth() -  textWidth) / 2.0f, textBaseline, paint);
    }

完全是按照步骤来实现的!

用法

<com.gyw.singlelinetextviewdemo.SingleLineTextView
            android:background="#ff0000"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:paddingTop="3dp"
            android:singleLine="true"
            gyw:textColor="#ffffff"
            gyw:textContent="A好好学习好好学习A"
            gyw:textSize="18sp" />

记住:
别忘记了命名空间

xmlns:gyw="http://schemas.android.com/apk/res-auto"

效果

源码

点击查看完整源码

最终效果出来了,程序员拿着实现了功能高高兴兴找产品经理,产品经理看了后说:“还是用省略号吧…“。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值