Подтвердить что ты не робот

ScrollView.scrollTo не работает? Сохранение позиции ScrollView при вращении

Хорошо.. Я должен упускать из виду что-то реальное просто здесь, но я думаю, что я пытаюсь сделать что-то довольно простое. Просто сохраните положение полосы прокрутки ScrollView при изменении ориентации...

Вот код для моего onSaveInstanceState и onRestoreInstanceState.. sView - это контейнер для макета ScrollView. В моем scrollview есть linearlayout с большим количеством текстовых просмотров.

    @Override 
public void onSaveInstanceState(Bundle outState) 
{
    //---save whatever you need to persist—

    outState.putInt("sViewX",sView.getScrollX());
    outState.putInt("sViewY",sView.getScrollY());

super.onSaveInstanceState(outState);

}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) 
{
    super.onRestoreInstanceState(savedInstanceState);

    sViewX = savedInstanceState.getInt("sViewX");   
    sViewY = savedInstanceState.getInt("sViewY");

    sView.scrollTo(sViewX, sViewY);

}

Если я устанавливаю Toast со значениями sViewX и sViewY в Restore, значения сохраняются и корректируются.

Изменить: я просто попытался сделать sView.scrollTo(0,150); в моем onCreate.. просто посмотреть, откроет ли это активность на 150 пикселей вниз, и это не так. Я думаю, что моя проблема связана с методом .scrollTo.

4b9b3361

Ответ 1

Я понял это.

Поскольку я использую setText для TextViews в моем onCreate, вызов .scrollTo не будет работать.

Итак, теперь я использую следующее:

sView.post(new Runnable() {
    @Override
    public void run() {
        sView.scrollTo(sViewX, sViewY);
    } 
});

Ответ 2

onRestoreInstanceState() только для ранней прокрутки представления. Вот почему публикация нового Runnable помогает, но не всегда. Иногда даже нужно использовать postDelayed(), чтобы он работал. Для Fragment вместо этого можно использовать onViewCreated():

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    sViewX = savedInstanceState.getInt("sViewX");   
    sViewY = savedInstanceState.getInt("sViewY");
    sView.scrollTo(sViewX, sViewY);
}

Ответ 3

Это работает для меня

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putInt(SystemGlobal.SCROLL_Y, mRelativeLayoutMain.getTop());
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onRestoreInstanceState(savedInstanceState);
    mRelativeLayoutMain.scrollTo(0, savedInstanceState.getInt(SystemGlobal.SCROLL_Y));
}

Ответ 4

Для MVVMCross:

protected override void OnSaveInstanceState(Bundle outState)
{
    base.OnSaveInstanceState(outState);

    ScrollView sv = FindViewById<ScrollView>(Resource.Id.dispatchScrollView);
    int posY = sv.ScrollY;

    outState.PutInt("scrollY", posY);
}

protected override void OnRestoreInstanceState(Bundle savedInstanceState)
{
    base.OnRestoreInstanceState(savedInstanceState);

    ScrollView sv = FindViewById<ScrollView>(Resource.Id.dispatchScrollView);
    int posY = savedInstanceState.GetInt("scrollY");

    sv.Post(new Runnable(new Action(() => sv.ScrollTo(0, posY))));
}

Ответ 5

Вы должны начать прокрутку перед рисованием компонентов, поскольку прокрутка не работает до тех пор, пока не будут созданы компоненты:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    scrollView.scrollTo(.... 

Ответ 6

Вместо того, чтобы отправлять действие прокрутки в следующий цикл цикла, вы можете прокручивать свое представление в глобальном обратном вызове макета:

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    sView.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                sView.scrollTo(sViewX, sViewY);
            }
        }
    );
}