【问题标题】:Save state of activity when orientation changes android当方向改变android时保存活动状态
【发布时间】:2020-04-27 21:17:49
【问题描述】:

我有一个 aacplayer 应用程序,当方向从纵向变为横向时,我想保存我的活动状态。 TextViews 似乎不是空的,我尝试使用以下方法冻结我的 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 会消失并显示为空。流媒体音乐效果很好。我可以在方向改变时收听它,但是每次我改变设备的方向时,textviews 中的文本都会消失。

我应该如何解决这个问题以便保存状态?

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

非常感谢。

【问题讨论】:

  • 你在使用 Action bar sherlock 库吗?
  • 没有兄弟,只有 android 2.3.3 api 就是这样
  • 给 android:freezesText="false"

标签: android


【解决方案1】:

当您的方向改变时,您不必手动更改为横向布局文件。 Android 会自动为您执行此操作。当方向改变时,Android 会破坏您当前的活动并再次创建一个新活动,这就是您丢失文本的原因。

假设您想要一个单独的纵向和横向布局,您需要做 2 个部分。

  1. 假设您有 2 个纵向和横向 XML 布局文件,请将您的 main.xml 布局文件放在以下文件夹中:

    res/layout/main.xml res/layout-land/main.xml

    这就是您需要做的所有事情,您不必触摸清单文件来修改android:configChanges="orientation" 或覆盖onConfigurationChanged()。实际上,建议您不要为您想要达到的目的而触摸它。

  2. 现在从文本视图中保存文本 =) 假设您的文本视图在布局 xml 文件中被命名为 MyTextView。您的活动将需要以下内容:

    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() 中填充你的文本视图。如果是第一次创建活动(不是由于轮换更改),则 savedInstanceState 在onCreate() 中将为空。你也可能不需要android:freezesText="true"

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

【讨论】:

  • 如果您还没有这样做,任何正在执行您的 aac 播放的对象都应该在服务中运行,而不是在您的活动中。您还可以使用片段将 aac 作为保留的单独片段播放,如果您有兴趣采用这种方法,可以在此处阅读有关片段的更多信息developer.android.com/guide/components/fragments.html
  • 你建议我不要使用 onconfigchanged 吗?我不需要添加 android:configChanges="orientation" 吗?我在这里做了一些研究,我发现我需要把它放在清单中。
  • 是的,我已经在使用服务,这是我的 oncreate 代码,我需要保存所有代码,因此当方向更改和布局也发生更改时,因为我有 layout-land .xml http://pastebin.com/4bM4u0C2
  • 不,我不建议使用 onConfigChanged。绕过Android破坏/重新创建旋转更改的活动基本上是一种技巧,因此这不是一个好习惯。 Android 设计为在旋转更改时销毁/重新创建活动是有原因的,因此您希望保留设计的行为。在早期的 Android 时代,人们使用它来快速破解它。您基本上可以在适合捆绑的旋转更改中保存您想要的任何内容,只需使用不同的键并在 onCreate() 中恢复它们
  • 如果您对保留片段有更多问题,您应该开始另一个问题线程 =) 我认为您关于“保持 textview 的文本旋转”的原始问题已得到解答
【解决方案2】:

有两种方法,第一种是在AndroidManifest.xml 文件中。您可以将其添加到您的活动标签中

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

或者你可以重写两个方法来解决这个问题。这种方法需要更多的努力,但可以说要好得多。 onSaveInstanceState 保存活动在被杀死之前的状态,onRestoreInstanceStateonStart() Refer to the official documentation 之后恢复该信息以进行更深入的查看。

在下面的示例代码中,我保存了 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);
    }

【讨论】:

    【解决方案3】:
    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。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多