1. 程式人生 > >Android解決TextView顯示希伯來語時Scroll,文字消失的問題

Android解決TextView顯示希伯來語時Scroll,文字消失的問題


    最近客戶報了一箇舊專案的問題:使用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

需要的請自己下載。