2011-03-21 157 views
4

在我的Android佈局中,我有一個TextView。這個TextView顯示一個相當大的spannable文本,並且能夠滾動。現在,當手機旋轉時,視圖被破壞並創建,並且我必須再次設置TextTe()TextView,將滾動位置重置爲開頭。如何在屏幕旋轉後恢復textview滾動位置?

我知道我可以使用getScrolly()和scrollTo()滾動到像素位置,但由於視圖寬度的變化,線條變得更長,這是在像素POS 400行現在可能是在250所以這不是很有幫助。

我需要一種方法來查找onDestroy()中的TextView中的第一個可見行,然後使TextView在旋轉後滾動到該特定段落的文本。

任何想法?

回答

1

TextView可以爲您保存和恢復其狀態。如果你不能夠使用,你可以禁用,並明確調用的方法:

http://developer.android.com/reference/android/widget/TextView.SavedState.html http://developer.android.com/reference/android/widget/TextView.html#onSaveInstanceState() http://developer.android.com/reference/android/widget/TextView.html#onRestoreInstanceState(android.os.Parcelable

+0

同樣的問題。 TextView只保存像素位置,而不是文本位置。旋轉後,我必須計算一個新的像素位置,以便與之前一樣顯示相同的文本。 – Josh 2011-05-06 20:40:51

11

這是一個古老的問題,但我在尋找相同問題的解決方案時登陸這裏,所以這就是我想出的。我結合從答案的想法以下三個問題:

我想從我的應用程序只提取相關的代碼,所以請原諒任何錯誤。另請注意,如果您旋轉到橫向並返回,它可能不會以您開始的相同位置結束。例如,說「彼得」是肖像中第一個可見的單詞。當你旋轉到風景時,「彼得」是其最後一個詞,第一個是「拉里」。當您旋轉回來時,「拉里」將會顯示。

private static float scrollSpot; 

private ScrollView scrollView; 
private TextView textView; 

protected void onCreate(Bundle savedInstanceState) { 
    textView = new TextView(this); 
    textView.setText("Long text here..."); 
    scrollView = new ScrollView(this); 
    scrollView.addView(textView); 

    // You may want to wrap this in an if statement that prevents it from 
    // running at certain times, such as the first time you launch the 
    // activity with a new intent. 
    scrollView.post(new Runnable() { 
     public void run() { 
      setScrollSpot(scrollSpot); 
     } 
    }); 

    // more stuff here, including adding scrollView to your main layout 
} 

protected void onDestroy() { 
    scrollSpot = getScrollSpot(); 
} 

/** 
* @return an encoded float, where the integer portion is the offset of the 
*   first character of the first fully visible line, and the decimal 
*   portion is the percentage of a line that is visible above it. 
*/ 
private float getScrollSpot() { 
    int y = scrollView.getScrollY(); 
    Layout layout = textView.getLayout(); 
    int topPadding = -layout.getTopPadding(); 
    if (y <= topPadding) { 
     return (float) (topPadding - y)/textView.getLineHeight(); 
    } 

    int line = layout.getLineForVertical(y - 1) + 1; 
    int offset = layout.getLineStart(line); 
    int above = layout.getLineTop(line) - y; 
    return offset + (float) above/textView.getLineHeight(); 
} 

private void setScrollSpot(float spot) { 
    int offset = (int) spot; 
    int above = (int) ((spot - offset) * textView.getLineHeight()); 
    Layout layout = textView.getLayout(); 
    int line = layout.getLineForOffset(offset); 
    int y = (line == 0 ? -layout.getTopPadding() : layout.getLineTop(line)) 
     - above; 
    scrollView.scrollTo(0, y); 
} 
+0

這工作得很好!應該被接受爲答案。 – Matt 2013-06-08 00:49:42