EditText数据在旋转设备时丢失



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

我有一个由2个EditText组成的登录屏幕。现在,这个登录屏幕具有不同的纵向和横向布局。所以我不得不在layout文件夹中创建一个login.xml,在layout land文件夹中创建另一个loginxml。为了支持方向更改,我重写了LoginActivity类中的ConfigurationChanged()方法。在这个方法中,我调用setContentView(R.layout.login)方法,以便将适当的login.xml设置为每个方向的布局。

在所有这些之后,我在我的清单文件中也定义了以下内容:

android:configChanges="orientation|keyboardHidden"

但我仍然面临着著名的老问题。如果Edittext中有任何文本,并且设备被旋转,则该文本将丢失。我不想丢失那条短信。这可能吗?我读到我们可以使用onSaveInstanceState(Bundle savedInstanceState)方法来完成它,我甚至也尝试过,但它对我不起作用。请帮助。提前谢谢。

使用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"。

祝你好运!

首先删除您所做的所有onConfigurationChangedconfigChanges=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);
    }
    

打开https://github.com/jcraane/AndroidBundleState您可以找到一个非常简单的库来处理状态逻辑。您所要做的就是为字段添加注释。

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

只需将其设置为登录文本和密码文本

text View.setSaveEnabled(false);

这可能是非常规的或过度的,但我发现将数据存储在Application类的捆绑包中对于Fragments和Activities来说是最成功和直观的。

在应用程序类中添加:

static class Bundles {
    static Bundle USER_BUNDLE = null;
}

然后在您的片段或活动中添加:

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

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

EditText视图(也称为TextInputEditText)将在设备旋转时保留其自己的状态,而无需像其他答案所描述的那样手动保存和恢复其状态。

最大的问题是,视图只有在指定了id的情况下才能保存其状态,因为这是保存数据的密钥。检查您的布局XML分配了一个id。如果使用TextInputLayout,内部TextInputEditText也需要一个id,即使您从未在代码中引用过它。类似这样的东西:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/my_text_input_layout"
    style="@style/MyTextInputLayoutStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/my_input_edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

在代码中方向即将改变的时刻,实现以下操作:

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

但这必须在屏幕改变方向之前放置。例如,当从设备摄像头返回到应用程序时,应用程序经常会无故返回并再次改变方向。

别忘了标记我=)

祝你好运。

最新更新