在做多语言适配的时候总会遇到一个很头疼的问题:某些内容中文只有短短两三个字,可翻译成英文之后就是一连串的字符,如果TextView的宽度是wrap_content
的话就会骤然变宽,把其它的控件挤到一边,整个界面显得特别凌乱。过去解决这种问题通常有两种方案:
固定TextView的宽高。保持了界面的美观和统一,但是字符过长时会显示不全;
为每种语言都写一个布局。这样可以适配不同语言的布局,但是由于布局过多,增加了后期的维护成本。
这两种方法都有局限,实际运用时问题也比较多。这时候你一定会想,假如TextView里面的文字能够根据TextView的宽高聪明地放缩就好了。那么恭喜你,TextView的新特性Autosizeing
可以满足你!
(详情参考这篇文章:文字太多?控件太小?试试 TextView 的新特性 Autosizeing 吧!)
不过这么好用的属性是在Android 8.0之后推出,在版本低于8.0的手机上面的使用会有一点不一样。首先你的Support包必须是26以上的,而且要使用AppCompatTextView
。布局中的写法如下:
<android.support.v7.widget.AppCompatTextView app:autoSizeTextType="uniform" app:autoSizeMinTextSize="12sp" app:autoSizeStepGranularity="2sp" app:autoSizeMaxTextSize="16sp" android:layout_width="wrap_content" android:layout_height="wrap_content" />
用法很简单,但是每次都要去设置这几个属性的话未免有点烦了,最好的做法当然是将其封装成一个style
,每次需要的时候去引用就可以了。
一开始我是这样写的:
<style name="AutoTextStyle"> …… <item name="android:autoSizeTextType" tools:targetApi="o">uniform</item> <item name="android:autoSizeMaxTextSize" tools:targetApi="o">16sp</item> <item name="android:autoSizeMinTextSize" tools:targetApi="o">12sp</item> <item name="android:autoSizeStepGranularity" tools:targetApi="o">2sp</item> </style>
这样显然无法在Android8.0以下的手机上奏效。于是我将命名空间换成了app:
,没有提示语法错误,但是编译时却报出了如下的错误:
Error:(1296, 21) No resource found that matches the given name: attr 'app:autoSizeMaxTextSize'.
其他的属性也是这样,说明在app:
这个命名空间下没有这样属性。那么命名空间应该怎么写呢?
根据博客styles.xml文件中@符号及命名空间android:的使用,在v7包中的属性并不是有android系统定义的,而是存在于当前工程之中。我们可以全局搜索一下values.xml,就是appbuildintermediatesappbuildintermediatesresdebugvalues下面的:
打开之后,搜索我们用到的TextView新属性,果然找到了:
可以看到它的前面是没有命名空间的,另外三个属性也是这样,大家可以自行查找一下。
回到我们的styles.xml文件,去掉前面的app:
命名空间:
<style name="AutoTextStyle"> …… <item name="autoSizeTextType" >uniform</item> <item name="autoSizeMaxTextSize" >16sp</item> <item name="autoSizeMinTextSize" >12sp</item> <item name="autoSizeStepGranularity" >2sp</item> </style>
再次编译,成功通过了。