Как восстановить положение прокрутки текста после поворота экрана? - PullRequest
4 голосов
/ 21 марта 2011

В моем макете Android у меня есть TextView. Этот TextView отображает довольно большой охватываемый текст и может прокручиваться. Теперь, когда телефон поворачивается, представление уничтожается и создается, и мне нужно снова установить TextText () TextView, сбросив позицию прокрутки в начало.

Я знаю, что могу использовать getScrolly () и scrollTo () для прокрутки к позициям пикселей, но из-за изменения ширины просмотра строки становятся длиннее, и линия, которая была в позиции 400 пикселя, теперь может быть на 250. Так что это не очень полезно.

Мне нужен способ найти первую видимую строку в TextView в onDestroy (), а затем способ заставить TextView прокручивать этот фрагмент текста после поворота.

Есть идеи?

Ответы [ 2 ]

13 голосов
/ 18 января 2013

Это старый вопрос, но я приземлился здесь при поиске решения той же проблемы, так что вот что я придумал.Я объединил идеи из ответов на эти три вопроса:

Я пытался извлечь из приложения только соответствующий код, поэтому, пожалуйста, прости любые ошибки.Также обратите внимание на то, что если вы поворачиваете в горизонтальное и обратное положение, оно может не заканчиваться в том же положении, в котором вы начали.Например, скажите «Питер» - первое видимое слово в портрете.Когда вы поворачиваетесь в пейзаж, «Питер» является последним словом в своей строке, а первое - «Ларри».Когда вы вернетесь назад, «Ларри» будет видно.

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 голос
/ 21 марта 2011

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)

...