屏幕旋转后如何恢复textview滚动位置?

时间:2011-03-21 18:29:34

标签: android textview screen-rotation

在我的Android布局中,我有一个TextView。此TextView显示一个相当大的spannable文本,它可以滚动。现在,当手机旋转时,视图将被销毁并创建,我必须再次将TextText()设置为TextView,将滚动位置重置为开头。

我知道我可以使用getScrolly()和scrollTo()来滚动到像素位置,但是由于视图宽度的变化,线条变得更长,并且位于像素位置400的线条现在可能是250.所以这不是很有帮助。

我需要一种方法在onDestroy()中查找TextView中的第一个可见行,然后在旋转后使TextView滚动到这段特定文本。

有什么想法吗?

2 个答案:

答案 0 :(得分:13)

这是一个老问题,但我在寻找同一问题的解决方案时落在这里,所以这就是我想出来的。我将这些问题的答案中的想法结合起来:

我尝试从我的应用中仅提取相关代码,所以请原谅任何错误。另请注意,如果您旋转到横向和后退,它可能不会以您开始的相同位置结束。例如,说“彼得”是肖像中的第一个可见单词。旋转到横向时,“Peter”是其行中的最后一个单词,第一个单词是“Larry”。当您向后旋转时,“拉里”将会可见。

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);
}

答案 1 :(得分: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