很多时候,文本显示是有限制的,有个maxline,然后要求你末尾截取,最后一行末尾是...(xxx文本...),那么只要在你的xml里设置 ellipsize_end 就行了,但是有时候往往需求就是千奇百怪,系统控件无法满足产品的要求

比如下图效果

这个textview在末尾要留一定的空白,因为末尾同行有个索引,这时候系统的end模式已经无法实现,如果你在xml中把textview的ellipsize设置为end,那么末尾文字会直接到最右边,跟后面的索引样式重叠了

设想

然后你可能会联想到一个常用的控件效果,折叠TextView,文字过长,末尾会显示全部,把多出文本收拢,然后在想,如果自己把全部设置成空格是不是就可以达到这个效果呢,当然,可以去看看大致源码实现,是否可行,当时为了偷懒,其实本人就是这么想的,

一看代码,感觉可行,因为我看到了一个属性 Layout,而Layout里有个方法, getLineCount(),这个方法可以获取文本的行数,行数我都知道,那怎么玩还不是自己说了算,于是就开搞了,一切很完美,效果nice,但是后面的...太短了,还是会遮住索引,然后为了偷懒,

就用一开始的设想,加空格解决了,反正都是不可见的,效果一样,想要隔多少,那还不是自己说了算,于是就仿照折叠textview的效果,把这个全部变成空格,这样末尾不就是空白了,完美收工

问题出现

空格是加了,加上后一看效果,一般情况很完美,但是有个特例,就是当文本差点到达 end 模式的要求时,就是假设你maxlie是2,但是标题文本就是差几个字符才会超出两行,那么此时,是触发不了ellipsize效果的,因为getLineCount()返回的是2,不会进入end模式中去,然后自己脑洞大开,继续延续之前的思路,空格大发,我留白的地方都是空格,那么居然文本差了几个空格,我给它不上不久行了,反正末尾都是留白,不影响,于是空格加上,这时候真正的问题就来了

死胡同

凡是都有个但是,经过自己测试,一般情况下,的确没问题,不过如果你的文本末尾是空格,那么end模式触发不了,然后自己就以为是文本空格没计算进去,遇上打个断点,但是发现的确文本末尾有很多空格,那时候还试了几次,一直叠加空格,因为担心空格不够没触发,后面加了一行空格了,还是那样,于是进入系统方法去查看,后面发现了问题所在,原来是getLineCount()方法还是返回2,我文本长度明明已经超过了这个长度,可是getLineCount()确好像对末尾的空格不计算长度,所以导致这个情况不起作用,然后就开始研究为什么getLineCount()返回2不是3,查了好多资料不管用,只要是空格就不会计算,然后自己还想过是不是后面直接加串文字,然后把那部分文字设置成透明颜色得了,越想越离谱了都

醒悟,换个思路

于是就是问了下群里的大佬,大佬说,我不管你getLineCount()是不是有什么问题,首先你要实现什么效果,然后我老实芭蕉的告诉他,我要这个,和那个,然后大佬说,自己自己测量一下有那么难?真是一语点醒梦中人啊,有时候陷进去了就很难从那个模式中出来,后来决定抛弃前面的设想不用getLineCount()了,自己测量文字,那不是很简单的事,为什么一定要现在那个getLineCount()上面,而且还有那么多骚操作,然后自己直接自定义了个简单的textview,直接重写setText方法,测量,然后直接substring简单,方便

上面还特意注释了getLineCount()这个吭,然后一步步测量,得到自己想要的信息,末尾因为要给索引留白,所以写的-6,这里可以自己配置,这里比较简单就固定了,run一下

但是少年,你以为这就完了?

此时你还会发现,测量是在初始化后,这个是异步的,刷新的时候你会发现会有闪烁,因为之前看过折叠textview之类控件的做法,所以知道需要加个flag,初始化后就不需要再次监听了

此时很完美,但是少年,你又以为就完了?

此时又回到了上面提到过的问题,如果我的内容刚好差几个字符满足条件呢,测量出来的line还是2,不会进入end模式,但是此时已经不需要getLineCount()了,因为line是自己测量的,当然也不需要空格大发了,骚操作要不得,我这里居然能测量算出超出两行,那么我也能算出是否超出1.7行,1.5行,只要你感想,我就敢做

加个判断,就算你差几个字符,我照样还是能让你进入end模式,你会发现这个时候很好扩展了,这自己的东西就是不一样哈,在run一下,很是完美,你会发现标题已经变成了

 

 后面的留白可以自己把控,最后看下效果图

使用跟原生一样,因为是重写的setText

posted on 2021-02-22 09:42  翻滚的咸鱼  阅读(474)  评论(0编辑  收藏  举报