屏幕旋转后如何恢复TextView的状态?

109
在我的应用程序中,我有一个TextView和一个EditText。两者都有数据。当屏幕方向改变时,EditText中的数据保留,但TextView中的数据会被清除。
有人能帮我找到一种保留TextView数据的方法吗?
9个回答

229

如果你想要强制你的TextView保存它的状态,你必须添加freezesText属性:

<TextView 
     ... 
     android:freezesText="true" />

根据freezesText的文档:

如果设置了这个属性,文本视图将包括它当前的完整文本以及类似当前光标位置等元数据在内,将其冰冻在其icicle中。默认情况下,此功能被禁用,当文本视图内容未存储在持久存储介质(例如内容提供者)中时,该功能可能是有用的。


13
为什么文本不像其他属性(文本选择、光标位置等)一样默认为“冻结/保存”呢?换句话说,有哪种情况下会有人更喜欢文本没有被保存? - Gautam
3
@Gautam 我猜通常 TextView 是由存储在 XML 中的静态字符串构建的,因此系统记住这些值是多余的。 - anderspitman
3
实际上,一旦给EditText或TextView分配了一个id,在屏幕旋转事件期间该值将保持不变。 - DoctorFox
7
很抱歉,至少在某些设备上(如Jellybean),对于 TextViews 来说情况并非如此。 - Bö macht Blau
1
对我来说不起作用,至少在API 17设备上不行。 - Ali Bdeir
显示剩余3条评论

28
为了在屏幕旋转时保留数据,您需要实现两种方法:
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    // Read values from the "savedInstanceState"-object and put them in your textview
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    // Save the values you need from your textview into "outState"-object
    super.onSaveInstanceState(outState);
}

5
为什么在onCreate中已有相同的Bundle可用时,需要使用onRestoreInstanceState? - slott
5
请查看此文档:http://developer.android.com/training/basics/activity-lifecycle/recreating.html。我猜想是因为系统会记录是否正在创建新活动或重新创建旧活动。onRestoreSavedInstance只在更少的情况下被调用-例如配置更改和由于内存限制而导致的活动销毁。 - Gusdor

6

Android不会自动处理这种事情。你需要手动保存所有数据。

你可以在活动中使用来保存值。

@Override
    public Object onRetainNonConfigurationInstance() {
        HashMap<String, Object> savedValues = new HashMap<String, Object>();
        savedValues.put("someKey", someData);           
        return savedValues;
    }

在活动的onCreate方法中使用以下代码加载已保存的对象:

HashMap < String, Object> savedValues 
     = (HashMap<String, Object>)this.getLastNonConfigurationInstance();

您还可以选择为活动禁用方向更改

<activity android:name=".Activity" android:screenOrientation="portrait" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>

无法覆盖onRetainNonConfigurationInstance()在android.support.v4.app.fragmentActivity中; 被覆盖的方法是final!! - Akash Dubey

6

1)并非所有具有ID的视图都保存它们的状态。Android小部件具有ID,用户可以更改其状态,似乎在软关闭时保存它们的状态。因此,EditText保存其状态,但TextView在软关闭时不保存其状态。

"据我所知,Android仅会尝试保存预期发生更改的内容的状态。这就是为什么它会保存EditText中的文本(用户可能会更改),而可能不会保存TextView的状态(通常保持静态)" - Mark M

因此,您可以选择在onSaveInstanceState中保存textview的状态,并选择在onCreate中恢复textview的状态。

2)最佳实践是即使声明了“内部”非视图实例状态,也要保存它。

android:configChanges= "orientation|keyboardHidden" 

来自文档:

"然而,你的应用程序应该始终能够在关闭和重新启动后保持其先前的状态。不仅因为有其他配置更改可能导致你的应用程序重新启动,而且还要处理事件,例如用户接收到来电然后返回到你的应用程序。"

JAL


1

在AndroidManifest.xml中修改您的活动以通过将以下内容添加到您的活动/活动来覆盖方向更改行为:

android:configChanges="orientation|keyboardHidden"

它应该看起来像这样:

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

27
通常情况下,文档不推荐使用这种方法(http://developer.android.com/guide/topics/manifest/activity-element.html#config):“应该避免使用此属性,并仅在最后的情况下使用。请阅读[处理运行时更改](http://developer.android.com/guide/topics/resources/runtime-changes.html)……” - idbrii

1

将以下内容添加到AndroidManifest.xml文件中
Activity_Name的位置上填写您的活动名称

<activity android:name="Activity_Name"
        android:screenOrientation="sensor"
        ...
        android:configChanges="orientation|keyboardHidden|screenSize">

这也适用于值改变的文本字段。

1

只需添加

android:configChanges="orientation|screenSize"

在AndroidManifest.xml文件中添加到您的Activity。

-2

当配置更改时,Android 默认会重新启动您的活动。要更改此行为,您应该覆盖 onConfigurationChanged() 方法。此外,您还应该将 android:configChanges 添加到您的清单文件中。

您可以 在这里 阅读更多内容。


-7

我也使用了

android:configChanges="orientation"

但是它没有起作用。

然后我找到了一个解决方案。

请验证您的清单中是否正确包含以下行:

<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="11" />

确保它不会读成类似的东西
<uses-sdk android`:minSdkVersion="11" android:targetSdkVersion="15" />`

我一开始是用第二种方式,但当我纠正后,状态得到了保留。


1
这是完全不同的事情。目标SDK是使您的应用程序与大多数Android操作系统版本兼容。这不是一个答案,某种程度上这可能在您的情况下起作用,但这不是一个适当的解决方案。 - Rohan Kandwal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接