您的位置:首页 > 移动开发 > Android开发

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 配置:
<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
需要的请自己下载。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  textview hebrew