第一篇博客
解决时长:7小时
-
方案一:根据加载后的内容动态调整字体大小,采用大小/行数获得新字体的大小,在view.post里调用,等待textview完成绘制,这时候才能获得textview的行数。
猜测可能是textview的绘制有个单独的线程。 -
方案二:采用逐步缩减字体大小的方法,使得textview刚好显示一行。网络上有作者已经完成。
Android 自动调整 TextView 文字大小仅显示一行。http://www.jianshu.com/p/637f63106177 -
方案三:在方案二的基础上,放开限制,判断
while (((Math.floor(heigh / mTextSize)) * availableWidth) < textTotalWidths + (Math.ceil(heigh / mTextSize) * mTextSize)) {
mPaint.setTextSize(--mTextSize);//这里传入的单位是 px
textTotalWidths = getTextLength(mTextSize, text);
}
行数*行容量是否大于总需求量。但是这时候碰到了一个问题,就是有时候字体会显示不全。查阅了一些资料,有些人说是padding的问题,但是我用代码和肉眼都检查了,应该没有padding的问题。此外当然也是不存在bound的问题,因为我没有设置。此外我也疑惑是不是单位的问题,但是试来试去,都用的pt像素这个单位。
最后我注意到了绘制这个问题 。发现getPaint()得到的Paint有可以用的接口可以获得绘制的行距。
这是我之前忽略的问题,行距就是一种空白,而且占据空间。由于我的代码没有设置任何边框和padding,所以不难推测textview完整显示文字所需要的的最小高度为mTextSize * ((x - 1) scale + 1)【推荐设置为xscale】。这里的scale经过我的计算显示为字体大小的1.225倍,就是行距,两条drawtext的基线距离。可能与机型有关,但是直接调用方法会出错。
通过下面这篇文章可以知道为,极限最小距离情况下,个别字体可能会超线,此外也不利于居中显示。
https://www.cnblogs.com/andy-songwei/p/10968358.html
这里就基本解决了问题。但是代码上我还有一个地方没解决。
这里我把获得最小字体希望在一个循环里解决,但是实际上,由于第一个循环目的是获得足够的行(而且不求完全显示),以容纳全部内容。第二个循环的进入要求则是,需求总高度大于实际可以提供的高度。两个循环运行存在一定冲突。
int x = (int) Math.floor(heigh / mTextSize);
float scale = mTextSize * ((x - 1) * 1.225f + 1);
while (scale > heigh) {
mTextSize--;
x = (int) Math.floor(heigh / mTextSize);
scale = mTextSize * ((x - 1) * 1.225f + 1);
}
实际上,就算单单从编程的角度上考虑,我也不应该力图在一个循环里完成所有任务。高内聚低耦合的原则,在这里也是适用的。只有把过程拆解清楚了,才能顺利到达。
Log.e("这是循环计算",
"\n" + getText()
+ "\n字体大小:" + mTextSize
+ "\n估算行数:" + (heigh / mTextSize)
+ "\n向下行数:" + (Math.floor(heigh / mTextSize))
+ "\n估算的最小可用容量:" + ((Math.floor(heigh / mTextSize)) * availableWidth)
+ "\n实际需要:" + textTotalWidths
+ "\\" + getScaleY() + "--" + getPaint().getFontSpacing());
运行结果如下:
2020-11-12 00:39:25.911 21533-21533/com.xueluoanping.lightchaser E/这是循环计算: 最好的圣诞礼物:泡沫冬景
字体大小:36.0
估算行数:2.25
向下行数:2.0
估算的最小可用容量:700.0
实际需要:432.0\1.0--44.1
最终测试:通过真机测试,但是只有debug模式是正常显示的。目前暂时不清楚原因。比较神奇的是小米6x直接就连接成功了,不需要安装驱动(也有可能是之前下过)。

浙公网安备 33010602011771号