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.
Ответы
Ответ 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);
}
}
);
}