【问题标题】:EditText data is lost on rotating the device旋转设备时 EditText 数据丢失
【发布时间】:2012-08-21 06:36:49
【问题描述】:

好的,伙计们,我已经完成了。过去两天我一直在谷歌搜索,但找不到确切的解决方案。每个人都在谈论 configChanges 和所有那些在我的情况下似乎不起作用的陈词滥调。

我有一个包含 2 个 EditTexts 的登录屏幕。现在这个登录屏幕有不同的纵向和横向布局。所以我必须在布局文件夹中创建一个 login.xml,在 layout-land 文件夹中创建另一个 login.xml。为了支持方向更改,我覆盖了 LoginActivity 类中的 onConfigurationChanged() 方法。在此方法中,我调用 setContentView(R.layout.login) 方法,以便将适当的 login.xml 设置为每个方向的布局。

毕竟,我还在清单文件中定义了以下内容:

android:configChanges="orientation|keyboardHidden"

但我仍然面临着著名的老问题。如果 Edittext 中有任何文本并且旋转了设备,则该文本将丢失。我不想丢失那个文本。有没有可能?我已经读到我们可以使用 onSaveInstanceState(Bundle savedInstanceState) 方法来做到这一点,我什至也尝试过,但它对我不起作用。请帮忙。提前致谢。

【问题讨论】:

    标签: android android-edittext orientation onconfigurationchanged


    【解决方案1】:

    使用 put 方法在 onSaveInstanceState 中存储值:

    protected void onSaveInstanceState(Bundle extra) {
      super.onSaveInstanceState(extra);
      extra.putString("text", "your text here");
    }
    

    并恢复onCreate中的值:

    public void onCreate(Bundle extra) {
      if (extra != null) {
        String value = extra.getString("text");
      }
    }
    

    编辑(实际工作):

    尝试从清单中删除 android:configChanges="orientation|keyboardHidden"。

    祝你好运!

    【讨论】:

    • 这正是我一直在做的,但它对我不起作用。
    • 而且您不应该在 onConfigurationChanged() 中调用 setContent() 方法,因为您为此创建了 layout 和 layout-land 文件夹。内容将自动更改。
    • 好吧,在这种情况下,数据仍然存在,但布局不会相应改变。
    • 尝试从清单中删除 android:configChanges="orientation|keyboardHidden"。
    • 在清单中设置 configChanges=orientation 可防止应用在方向更改时重新创建。
    【解决方案2】:

    首先删除你所做的所有onConfigurationChanged 和configChanges=orientation 的东西——这个解决方案是为弱者准备的。然后执行以下操作:

    1. 覆盖 onRetainNonConfigurationInstance() 以便它返回您需要在设备旋转时保存的文本。您可能需要创建一个包含这些值的简单对象 - 例如:

      public class TextObject {
          public String loginText;
          public String passwordText;
      }
      
    2. 在 onCreate 中,初始化视图后,尝试通过getLastNonConfigurationInstance() 从旋转中获取保存的对象。如果这是您第一次通过 onCreate,这将返回 null,因此您需要进行 null 检查。示例:

      TextObject mySavedTextObject = (TextObject) getLastNonConfigurationInstance();
      if(mySavedTextObject!=null) {
        myLoginEditText.setText(mySavedTextObject.loginText);
        myPasswordEditText.setText(mySavedTextObject.passwordText);
      }
      

    【讨论】:

    • 这似乎也是一个好方法。我也会试试的。谢谢,我 +1。
    【解决方案3】:

    在https://github.com/jcraane/AndroidBundleState 上,您会发现一个非常简单的库为您处理状态逻辑。您所要做的就是注释您的字段。

    @BundleState("state_name") 私有字符串名称; 在rotationChange之后,该库将为您恢复字段中的值。

    【讨论】:

      【解决方案4】:

      只需为您的登录文本和密码文本设置此项

      textView.setSaveEnabled(false);

      【讨论】:

        【解决方案5】:

        这可能是非常规的或矫枉过正的,但我发现在应用程序类中以捆绑包的形式存储数据对于片段和活动来说最为普遍和直观。

        在您的应用程序类中添加:

        static class Bundles {
            static Bundle USER_BUNDLE = null;
        }
        

        然后在您的 Fragment 或 Activity 中添加:

        private String username = "";
        
        @Override
        public void onSaveInstanceState(@NonNull Bundle extra) {
            super.onSaveInstanceState(extra);
            EditText txtUsername = v.findViewById(R.id.user_name);
            String username = txtUsername==null ? "" : txtUsername.getText().toString();
            MyApplication.Bundles.USER_BUNDLE = new Bundle();
            MyApplication.Bundles.USER_BUNDLE.putString("User.username", username);     
        }
        
        @Override
        public void onCreate(Bundle extra) {
            super.onCreate(extra);
            if (MyApplication.Bundles.USER_BUNDLE != null) {
                username = MyApplication.Bundles.USER_BUNDLE.getString("User.username", "");
            }
        }
        

        然后无论您在哪里设置视图组件,都添加如下内容:

        EditText txtUsername = v.findViewById(R.id.user_name);
        if (txtUsername!=null) txtUsername.setText(username);
        

        添加不同类型的多个值很容易,如果您使用片段,您甚至可以在它们之间共享数据。

        【讨论】:

          【解决方案6】:

          在代码中方向即将改变的点(时间),实现:

          this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
          

          但这必须在屏幕改变方向之前放置,例如在从设备相机返回到您的应用程序时,经常会发生应用程序无故返回并再次更改方向的情况。

          别忘了标记我 =)

          祝你好运。

          【讨论】:

            猜你喜欢
            • 2020-08-02
            • 1970-01-01
            • 2011-07-04
            • 1970-01-01
            • 2011-03-03
            • 1970-01-01
            • 2013-12-21
            • 2021-05-27
            • 2014-01-29
            相关资源
            最近更新 更多