Android解决TextView显示希伯来语时Scroll,文字消失的问题
2015-12-23 10:42
716 查看
最近客户报了一个旧项目的问题:使用TextView显示希伯来语时,文字会消失不见。经过查看后我解决了这个问题。问题的答案比较简单,但是寻找答案的方式可以借鉴、或者说反省一下。
先说解决的方案,经过检查,发现正常显示希伯来语时没问题,一Scroll就有问题了,即调用了TextView的ScrollTo方法之后,不管传什么值,包括ScrollTo(0,0),文字都会消失。然后显示其他文字是没有这个问题的,莫非是TextView绘制文字的时候有问题?
问题看起来很牛逼,所以我打起了12分精神,打算跟它死磕一下。
在查看代码之前,其实我已经知道了希伯来语默认是右对齐的,也是从右往左读的,在网上搜索了一番没有答案之后,我打算调试TextView的源代码,查看绘制文字时是不是出问题了。怎么调试是个问题。本想从TextView派生一个类,重写onDraw函数并完全使用TextView的onDraw代码,然后发现onDraw里面使用了很多TextView的私有方法和成员,无法编译通过,思考之后觉得可以把TextView的源代码拷贝出来改个名字为MyTextView,一番折腾之后成功,期间遇到2个问题:
A.TextView源码中依赖的一些类,android SDK中没有,解决方法:使用一个外部SDK jar包, 可能是从系统源码编译之后产生的SDK jar包,是最终部署到机器上的那个。
B.编译器报错:"Field requires API level 18 (current min is 16): android.text.TextDirectionHeuristics#LOCALE",解决方法:右击工程->Android Tools->clear Lint Markers.
以上2个问题虽然解决了,但是原因不详,有知道的大神麻烦告知下。
编译成功之后就可以调试了,先看看xml 配置:
一番调试下来之后发现:在onDraw函数中,TextView正常绘制文字时,mScrollX的值竟然是1048176!然后随便scrollTo一下之后,文字就消失不见了。 为什么mScrollX的值是1048176,它默认是0呀,而且为什么值是1048176才能正常绘制文字呢?
知道TextView Scroll的实现方式的同学可能已经知道答案了,没错,原来是在测量TextView大小的时候发现TextView是singleLine,并且可以scroll, 所以赋给了TextView一个非常大的宽度值:
如果这个时候选择文字右对齐,会发生什么事情?
没错:scroll到最右边的一个位置:VERY_WIDE - TextView的mWidth,在此例中就是:
1024*1024 - 400 = 1048176;
这就是为什么mScrollX的值为1048176;这个时候scroll到(0,0)位置的话,那是毛都没有啊。
最后一个问题,TextView默认是左对齐的,为什么显示希伯来语是就变成了右对齐呢?
这个是文字布局器做的工作,布局器发现显示的是希伯来语,然后配置又没有指定左右对齐方式时,就把布局改成了右对齐,
这个是这种语言的特性决定的!
那么最后解决这个问题的方法就是把TextView的文字对齐方式显示指定为左对齐,即:
看吧,问题的答案简单到丧心病狂!我却折腾了老半天,本来早就知道希伯来文跟其他文字的区别就是右对齐,直接改成左对齐不久完了嘛,还折腾这么久...
听大神都说解决问题要大胆假设、小心求证,我一看到这个问题就怀疑是TextView代码有问题,一头栽进了代码里,结果啪啪的打了自己的脸!
本文使用的demo只能在Android4.1下运行,已经放到了以下URL:
http://download.csdn.net/detail/romantic_energy/9373198
需要的请自己下载。
先说解决的方案,经过检查,发现正常显示希伯来语时没问题,一Scroll就有问题了,即调用了TextView的ScrollTo方法之后,不管传什么值,包括ScrollTo(0,0),文字都会消失。然后显示其他文字是没有这个问题的,莫非是TextView绘制文字的时候有问题?
问题看起来很牛逼,所以我打起了12分精神,打算跟它死磕一下。
在查看代码之前,其实我已经知道了希伯来语默认是右对齐的,也是从右往左读的,在网上搜索了一番没有答案之后,我打算调试TextView的源代码,查看绘制文字时是不是出问题了。怎么调试是个问题。本想从TextView派生一个类,重写onDraw函数并完全使用TextView的onDraw代码,然后发现onDraw里面使用了很多TextView的私有方法和成员,无法编译通过,思考之后觉得可以把TextView的源代码拷贝出来改个名字为MyTextView,一番折腾之后成功,期间遇到2个问题:
A.TextView源码中依赖的一些类,android SDK中没有,解决方法:使用一个外部SDK jar包, 可能是从系统源码编译之后产生的SDK jar包,是最终部署到机器上的那个。
B.编译器报错:"Field requires API level 18 (current min is 16): android.text.TextDirectionHeuristics#LOCALE",解决方法:右击工程->Android Tools->clear Lint Markers.
以上2个问题虽然解决了,但是原因不详,有知道的大神麻烦告知下。
编译成功之后就可以调试了,先看看xml 配置:
<com.example.hebrew.MyTextView android:text="@string/hebrew_text_short" android:id="@+id/short_text" android:layout_width="400px" android:layout_height="wrap_content" android:gravity="bottom" android:ellipsize="marquee" android:height="28sp" android:singleLine="true" android:textColor="#000" android:textSize="28sp" android:background="#aaaaaa"/>
一番调试下来之后发现:在onDraw函数中,TextView正常绘制文字时,mScrollX的值竟然是1048176!然后随便scrollTo一下之后,文字就消失不见了。 为什么mScrollX的值是1048176,它默认是0呀,而且为什么值是1048176才能正常绘制文字呢?
知道TextView Scroll的实现方式的同学可能已经知道答案了,没错,原来是在测量TextView大小的时候发现TextView是singleLine,并且可以scroll, 所以赋给了TextView一个非常大的宽度值:
private static final int VERY_WIDE = 1024*1024; protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ... if (mHorizontallyScrolling) want = VERY_WIDE; int hintWant = want; ... }
如果这个时候选择文字右对齐,会发生什么事情?
没错:scroll到最右边的一个位置:VERY_WIDE - TextView的mWidth,在此例中就是:
1024*1024 - 400 = 1048176;
这就是为什么mScrollX的值为1048176;这个时候scroll到(0,0)位置的话,那是毛都没有啊。
最后一个问题,TextView默认是左对齐的,为什么显示希伯来语是就变成了右对齐呢?
这个是文字布局器做的工作,布局器发现显示的是希伯来语,然后配置又没有指定左右对齐方式时,就把布局改成了右对齐,
这个是这种语言的特性决定的!
那么最后解决这个问题的方法就是把TextView的文字对齐方式显示指定为左对齐,即:
<span style="font-size:18px;">android:gravity="left"</span>
看吧,问题的答案简单到丧心病狂!我却折腾了老半天,本来早就知道希伯来文跟其他文字的区别就是右对齐,直接改成左对齐不久完了嘛,还折腾这么久...
听大神都说解决问题要大胆假设、小心求证,我一看到这个问题就怀疑是TextView代码有问题,一头栽进了代码里,结果啪啪的打了自己的脸!
本文使用的demo只能在Android4.1下运行,已经放到了以下URL:
http://download.csdn.net/detail/romantic_energy/9373198
需要的请自己下载。
相关文章推荐
- Android的TextView与Html相结合的具体方法
- Android中实现为TextView添加多个可点击的文本
- android textview 显示html方法解析
- Android开发技巧之在a标签或TextView控件中单击链接弹出Activity(自定义动作)
- Android实现TextView中文字链接的4种方式介绍及代码
- android TextView属性的详细介绍 分享
- Android编程中TextView宽度过大导致Drawable无法居中问题解决方法
- android TextView加下划线的方法
- android TextView多行文本(超过3行)使用ellipsize属性无效问题的解决方法
- Android编程中TextView字体属性设置方法(大小、字体、下划线、背景色)
- android显示TextView文字的倒影效果实现代码
- Android控件之TextView的分析探究
- TextView显示系统时间(时钟功能带秒针变化
- Android编程实现TextView字体颜色设置的方法小结
- Android编程实现TextView部分颜色变动的方法
- android TextView不用ScrollViewe也可以滚动的方法
- android开发教程之textview内容超出屏幕宽度显示省略号
- android Textview文字监控(Textview使用方法)
- 解析在Android中为TextView增加自定义HTML标签的实现方法
- Android编程实现TextView部分颜色变动的方法