简体   繁体   English

当方向改变android时保存活动状态

[英]Save state of activity when orientation changes android

I have an aacplayer app and I want to save the state of my activity when orientation changes from portrait to landscape.我有一个 aacplayer 应用程序,当方向从纵向变为横向时,我想保存我的活动状态。 The TextViews do not appear to be empty, I tried to freeze my textview using this: TextViews 似乎不是空的,我尝试使用以下方法冻结我的文本视图:

android:freezesText="true"

my manifest:我的清单:

android:configChanges="orientation"

I also tried this:我也试过这个:

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

So when orientation changes to landscape I can see my layout-land main2.xml, that works but my textview goes out and appears empty.因此,当方向更改为横向时,我可以看到我的 layout-land main2.xml,这有效,但我的 textview 消失并显示为空。 Streaming music works great.流媒体音乐效果很好。 I can listen to it when orientation changes, but the text inside textviews are gone each time I change the orientation of my device.当方向改变时我可以收听它,但是每次我改变设备的方向时,textviews 中的文本都消失了。

What should I do to fix this so I can save the state?我应该怎么做才能解决这个问题,以便保存状态?

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
....
....

Thank you very much.非常感谢你。

When your orientation changes, you don't have to manually change to the landscape layout file.当您的方向发生变化时,您不必手动更改为横向布局文件。 Android does this automatically for you. Android 会自动为您执行此操作。 When orientation changes, Android destroys your current activity and creates a new activity again, this is why you are losing the text.当方向改变时,Android 会破坏您当前的活动并再次创建一个新活动,这就是您丢失文本的原因。

There are 2 parts you need to do, assuming you want a separate layout for portrait and landscape.假设您想要纵向和横向的单独布局,您需要做两部分。

  1. Assuming you have 2 XML layout files for portrait and landscape, put your main.xml layout file in the following folders:假设您有 2 个用于纵向和横向的 XML 布局文件,请将您的 main.xml 布局文件放在以下文件夹中:

    res/layout/main.xml <-- this will be your portrait layout res/layout/main.xml <-- 这将是你的纵向布局
    res/layout-land/main.xml <-- this will be your landscape layout res/layout-land/main.xml <-- 这将是您的横向布局

    That's all you need to do, you don't have to touch the manifest file to modify android:configChanges="orientation" or override the onConfigurationChanged() .这就是您需要做的所有事情,您不必触摸清单文件来修改android:configChanges="orientation"或覆盖onConfigurationChanged() Actually, it's recommended you do not touch this for what you are trying to achieve.实际上,建议您不要为了您要实现的目标而触摸它。

  2. Now to save your text from the text view =) Lets assume your textview is named as MyTextView in your layout xml file.现在从文本视图中保存您的文本 =) 让我们假设您的文本视图在布局 xml 文件中被命名为 MyTextView。 Your activity will need the following:您的活动将需要以下内容:

     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()); }

Basically, whenever Android destroys and recreates your Activity for orientation change, it calls onSaveInstanceState() before destroying and calls onCreate() after recreating.基本上,每当 Android 销毁并重新创建您的 Activity 以更改方向时,它都会在销毁之前调用onSaveInstanceState()并在重新创建之后调用onCreate() Whatever you save in the bundle in onSaveInstanceState, you can get back from the onCreate() parameter.无论您在 onSaveInstanceState 包中保存什么,都可以从onCreate()参数中获取。

So you want to save the value of the text view in the onSaveInstanceState() , and read it and populate your textview in the onCreate().所以你想在onSaveInstanceState()保存文本视图的值,然后读取它并在 onCreate() 中填充你的文本视图。 If the activity is being created for the first time (not due to rotation change), the savedInstanceState will be null in onCreate() .如果活动是第一次创建(不是由于轮换更改),则onCreate()的 savedInstanceState 将为空。 You also probably don't need the android:freezesText="true"你也可能不需要android:freezesText="true"

You can also try saving other variables if you need to, since you'll lose all the variables you stored when the activity is destroyed and recreated.如果需要,您也可以尝试保存其他变量,因为当活动被销毁和重新创建时,您将丢失所有存储的变量。

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);
}

Its work for me.它为我工作。 But I think its not good code style and architecture for android.但我认为它不是很好的代码风格和 android 架构。

There are two ways of doing this, the first one is in the AndroidManifest.xml file.有两种方法可以做到这一点,第一种是在AndroidManifest.xml文件中。 You can add this to your activity's tag您可以将此添加到您的活动标签中

android:configChanges="keyboardHidden|orientation|screenSize|screenLayout"

Or you can override two methods that will take care of this.或者您可以覆盖两个处理此问题的方法。 This method requires some more effort, but arguably is much better.这种方法需要更多的努力,但可以说要好得多。 onSaveInstanceState saves the state of the activity before it's killed, and onRestoreInstanceState restores that information after onStart() Refer to the official documentation for a more in depth look. onSaveInstanceState保存活动被杀死之前的状态,而onRestoreInstanceStateonStart()之后恢复该信息。 请参阅官方文档以获得更深入的了解。

In my sample code below, I am saving 2 int values, the current selection from the spinner as well as a radio button.在下面的示例代码中,我保存了 2 个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);
    }

I use in KOTLIN static var / val :我在KOTLIN静态 var / val 中使用:

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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM