方向改变时保存scrollview的位置

问题描述 投票:0回答:7

这是我的布局:

detail layout

我需要在方向改变时保存滚动位置。例如,如果屏幕在纵向模式下显示从中间名开始的布局,则在横向模式下也应从相同的位置开始。

android android-layout orientation
7个回答
66
投票

只需在滚动元素上设置 android:id 即可。您的视图将自动保存其滚动位置。

来自 View.java 的代码:15554

protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
    if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) {
        mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
        Parcelable state = onSaveInstanceState();
        if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
            throw new IllegalStateException(
                    "Derived class did not call super.onSaveInstanceState()");
        }
        if (state != null) {
            // Log.i("View", "Freezing #" + Integer.toHexString(mID)
            // + ": " + state);
            container.put(mID, state);
        }
    }
}

44
投票

要在手机方向更改时保存和恢复 ScrollView 的滚动位置,您可以执行以下操作: 在onSaveInstanceState方法中保存当前位置:

protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putIntArray("ARTICLE_SCROLL_POSITION",
            new int[]{ mScrollView.getScrollX(), mScrollView.getScrollY()});
}

然后在onRestoreInstanceState方法中恢复位置。请注意,我们需要将 Runnable 发布到 ScrollView 才能使其正常工作:

protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    final int[] position = savedInstanceState.getIntArray("ARTICLE_SCROLL_POSITION");
    if(position != null)
        mScrollView.post(new Runnable() {
            public void run() {
                mScrollView.scrollTo(position[0], position[1]);
            }
        });
}

在谷歌上找到了这个解决方案。感谢 Original Coder。 :)


0
投票

在我的三星平板电脑上,我不必添加那么多代码(只需调用超类)。另外,我已经在 ListView 上有了一个名字。

protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
}

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/search_text"
        android:maxLines="1"
        android:inputType="text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="Enter search string here" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="doSearch"
        android:clickable="true"
        android:text="Search"
        android:layout_toRightOf="@id/search_text"/>

    <ListView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/list_of_books"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/search_text"
        android:divider="@null"
        android:orientation="vertical" />

</RelativeLayout>

0
投票

当配置更改或 Activity 由于内存不足而被终止时,Android 操作系统会保留 UI 状态。这包括但不限于

RecyclerView
滚动位置和
EditText
内的字符串。

但是,您必须设置 UNIQUE id

android:id
才能让 Android 操作系统处理此问题。



-5
投票

在清单中执行此操作..

  <activity
        android:name=".YourActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:label="@string/app_name" >
  </activity>

-15
投票

你如果你的活动没有改变任何轮换,你可以使用 android:configChanges="orientation|keyboardHidden|screenSize" 在此特定活动的清单文件中。但这显然是一种解决方法,而不是一个正确的解决方案。

注意:

如果你需要对横向和纵向使用不同的视图,或者如果你需要对不同的设备使用不同的视图,应该使用bundle并在saveinstancestate中保存数据并在oncreate中检索数据。此方法停止重新创建活动,并且活动假设事情将由用户自己处理。

© www.soinside.com 2019 - 2024. All rights reserved.