当屏幕方向改变时,保存Android活动状态

23
我有一个aacplayer应用程序,当方向从竖屏变为横屏时,我想保存活动状态。TextView似乎不为空,我尝试使用以下代码冻结我的TextView:

我有一个aacplayer应用程序,当方向从竖屏变为横屏时,我想保存活动状态。TextView似乎不为空,我尝试使用以下代码冻结我的TextView:

android:freezesText="true"

我的清单:

android:configChanges="orientation"

我也尝试了这个:

@Override
    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);
        setContentView(R.layout.main2);

当屏幕方向变为横向时,我可以看到layout-land main2.xml中的布局,这很好,但我的TextView消失了并且没有显示文本。流式音乐运作得很好,当屏幕方向改变时我仍然可以听音乐,但每次改变设备方向时TextView内的文本都会消失。

我应该怎么做才能修复这个问题,使得我可以保存状态?

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
....
....
非常感谢。

你是否正在使用Action Bar Sherlock库? - RajeshVijayakumar
1
不好意思,只有 Android 2.3.3 API,没有其他的。 - alexistkd
给android:freezesText="false" - RajeshVijayakumar
4个回答

62
当你改变屏幕方向时,你不必手动切换到横屏布局文件。Android会自动为您完成此操作。当屏幕方向更改时,Android会销毁您当前的Activity并重新创建一个新的Activity,这就是您丢失文本的原因。
有两个部分需要注意,假设您想要单独为纵向和横向设计布局。
1. 假设您已经有了用于纵向和横向的两个XML布局文件,请将主要的layout文件放在以下文件夹中: res/layout/main.xml <-- 这将是您的竖屏布局 res/layout-land/main.xml <-- 这将是您的横屏布局
这就是您需要做的全部,您不必修改清单文件来修改android:configChanges="orientation"或覆盖onConfigurationChanged()。实际上,建议您不要触及这些内容,以实现您所需的效果。
2. 现在是保存您在textView中的文本 =) 假设您的textView在您的布局xml文件中命名为MyTextView。你的Activity将需要以下内容:
private TextView mTextView;
private static final String KEY_TEXT_VALUE = "textValue";

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   mTextView = (TextView) findViewById(R.id.main);
   if (savedInstanceState != null) {
      CharSequence savedText = savedInstanceState.getCharSequence(KEY_TEXT_VALUE);
      mTextView.setText(savedText);
   }
}

@Override
protected void onSaveInstanceState (Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putCharSequence(KEY_TEXT_VALUE, mTextView.getText());
}
基本上,每当Android为了方向改变而销毁并重新创建Activity时,它会在销毁之前调用onSaveInstanceState(),并在重建后调用onCreate()。您在onSaveInstanceState中保存的任何内容都可以从onCreate()参数中获取回来。

因此,您需要在onSaveInstanceState()中保存文本视图的值,并在onCreate()中读取它并填充您的文本视图。如果该活动是第一次创建(不是由于旋转更改),则onCreate()中的savedInstanceState将为空。您还可能不需要android:freezesText =“true”

如果需要,您还可以尝试保存其他变量,因为在Activity被销毁和重新创建时,您存储的所有变量都将丢失。


2
如果你还没有这样做,无论是什么对象在进行AAC播放时都应该在服务中运行,而不是在你的活动中。你也可以使用片段将AAC播放作为一个单独的保留片段,如果你有兴趣采用这种方法,你可以在这里阅读更多关于片段的信息http://developer.android.com/guide/components/fragments.html。 - hiBrianLee
无论如何,简单的解释是,在您的Streaming对象中,将其放入非UI片段中,例如StreamingFragment。在StreamingFragment.onCreate()中,您将执行setRetainInstance(true)。此片段将拥有您的流媒体对象。在主活动中,您将通过FragmentManager通过findFragmentByTag添加此StreamingFragment。如果您想了解更多信息,请查看来自Google的FragmentRetainInstance示例。在这个示例中,您的StreamingFragment将是RetainedFragment - http://goo.gl/yGqCL请检查“添加没有UI的片段”一节。 - hiBrianLee
1
如果您对保留片段有更多问题,您应该开始另一个问题线程=)我认为您关于“在旋转时保留textview的文本”的原始问题已得到解答。 - hiBrianLee
“layout-land”现在还支持吗?我正在尝试使用它,但是它没有获取我放置在“layout-land”中的布局。谢谢。 - natsumiyu
正如你所提到的,没有必要添加android:configChanges="orientation"。但在我的情况下,我使用configChanges来避免移动设备中的横向模式,那么我该如何通过在manifest文件中添加configChanges来解决这个问题呢? - Dhruv Tyagi
显示剩余12条评论

4
有两种方法可以做到这一点,第一种方法是在 AndroidManifest.xml 文件中。你可以将以下内容添加到你的 activity 标签中。
android:configChanges="keyboardHidden|orientation|screenSize|screenLayout"

或者,您可以覆盖两个方法来处理这个问题。这种方法需要更多的努力,但可以说更好。 onSaveInstanceState 在活动被终止之前保存活动的状态,onRestoreInstanceStateonStart() 之后恢复该信息。请参阅官方文档以获取更深入的了解。

在下面的示例代码中,我保存了两个int值:来自微调器的当前选择和一个单选钮。

 @Override
    public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
        spinPosition = options.getSelectedItemPosition();
        savedInstanceState.putInt(Constants.KEY, spinPosition);
        savedInstanceState.putInt(Constants.KEY_RADIO, radioPosition);
        super.onSaveInstanceState(savedInstanceState);

    }

    // And I am restoring those values with `getInt`, then I can pass those stored values into the spinner and radio button group to select the same values that we saved earlier. 

    @Override
    public void onRestoreInstanceState(@NotNull Bundle savedInstanceState) {
        spinPosition = savedInstanceState.getInt(Constants.KEY);
        radioPosition = savedInstanceState.getInt(Constants.KEY_RADIO);
        options.setSelection(spinPosition, true);
        type.check(radioPosition);
        super.onRestoreInstanceState(savedInstanceState);
    }

1
static CharSequence savedText;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if(savedText != null) {
        TextView mTextView = (TextView) findViewById(R.id.main);
        mTextView.setText(savedText);
    }
}

// Another function in activity, when you change text
public void actionButton(View view) {
    // Change and save text in textView
    savedText = "Change text";
    mTextView.setText(savedText);
}

它对我有用。 但我认为这不是适合 Android 的良好代码风格和架构。


0

我在 KOTLIN 中使用静态变量 / 常量:

class MyFragment : Fragment()
{
     //all my code
     //access to static vars -> MyStaticClass.hello
}

class MyStaticClass 
{
    companion object {
        var hello: String = "Static text"
        var number_static: Int = 0
    }
}

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