如何防止自定义视图在屏幕方向改变时丢失状态?
简介
在 Android 应用中,我们经常会遇到用户更改设备屏幕方向的情况,例如从纵向切换到横向。在这种情况下,我们可能会发现应用中的一些视图会丢失其状态。例如,当用户在文本框中输入一些数据,然后更改屏幕方向时,之前输入的数据可能会被清除。为了防止这种情况发生,我们需要存储该视图的状态。本文将探讨如何在 Android 中防止自定义视图在屏幕方向改变时丢失状态。
实现
我们将创建一个简单的应用程序,其中显示一个 TextView 用于显示应用程序标题。然后,我们将创建一个 EditText 供用户输入数据,以及一个 Button 用于显示 Toast 消息。现在,我们将使用 Android Studio 创建一个新的项目。
步骤 1:在 Android Studio 中创建新项目
导航到 Android Studio,如下面的屏幕所示。在下面的屏幕中,点击“新建项目”以创建一个新的 Android Studio 项目。
点击“新建项目”后,您将看到下面的屏幕。
在此屏幕中,我们只需选择“空活动”,然后点击“下一步”。点击“下一步”后,您将看到下面的屏幕。
在此屏幕中,我们只需指定项目名称。然后包名将自动生成。
注意:确保选择语言为 Java。
指定所有详细信息后,点击“完成”以创建一个新的 Android Studio 项目。
项目创建完成后,我们将看到两个打开的文件:activity_main.xml 和 MainActivity.java 文件。
步骤 2:使用 activity_main.xml
导航到 activity_main.xml。如果此文件不可见,则要打开此文件,在左侧窗格中导航到 app > res > layout > activity_main.xml 以打开此文件。打开此文件后,将以下代码添加到其中。代码中添加了注释,以便详细了解。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <!-- on below line creating a text view for heading --> <TextView android:id="@+id/idTVHeading" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_margin="10dp" android:padding="4dp" android:text="Prevent Custom Views from loosing state across screen orientation changes in Android" android:textAlignment="center" android:textColor="@color/black" android:textSize="18sp" android:textStyle="bold" /> <!-- on below line creating a text view for displaying a response message --> <EditText android:id="@+id/idEdtMsg" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/idTVHeading" android:layout_margin="10dp" android:hint="Enter your name" /> <!-- on below line creating a button --> <Button android:id="@+id/idBtnDisplayToast" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/idEdtMsg" android:layout_margin="10dp" android:text="Display Toast Message" android:textAllCaps="false" /> </RelativeLayout>
说明:在上面的代码中,我们创建了一个根布局作为相对布局。在此布局内,我们创建了一个 TextView 用于显示应用程序标题。然后,我们创建了一个 EditText,用户可以在其中添加其姓名以在 Toast 消息中显示。然后,我们创建了一个 Button 用于显示 Toast 消息。最后,我们添加了相对布局的结束标签。
步骤 3:使用 MainActivity.java 文件
导航到 MainActivity.java。如果此文件不可见,则要打开此文件,在左侧窗格中导航到 app > res > layout > MainActivity.java 以打开此文件。打开此文件后,将以下代码添加到其中。代码中添加了注释,以便详细了解。
package com.example.java_test_application; import android.os.Bundle; import android.os.PersistableBundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class MainActivity extends AppCompatActivity { // creating variables for text view on below line. private EditText msgEdt; private Button displayToastBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //initializing variable for text view and button on below line. msgEdt = findViewById(R.id.idEdtMsg); displayToastBtn = findViewById(R.id.idBtnDisplayToast); // on below line checking if the saved state is not null. if (savedInstanceState != null) { // on below line setting the data from the saved state to our edit text. msgEdt.setText(savedInstanceState.getString("message")); } // on below line adding click listner for our button. displayToastBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // on below line displaying a toast message. Toast.makeText(MainActivity.this, "Hello " + msgEdt.getText().toString(), Toast.LENGTH_SHORT).show(); } }); } // on below line creating a method to saved the instance state. @Override public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) { super.onSaveInstanceState(outState, outPersistentState); // on below line setting outstate to set put the data. outState.putString("message", msgEdt.getText().toString()); } }
说明:在上面的代码中,首先我们为 EditText 和 Button 创建变量。现在,我们将看到 onCreate 方法。这是每个 Android 应用程序的默认方法。此方法在创建应用程序视图时调用。在此方法中,我们设置内容视图,即名为 activity_main.xml 的布局文件,以从该文件中设置 UI。在 onCreate 方法中,我们使用我们在 activity_main.xml 文件中给定的 ID 初始化 EditText 和 Button 变量。
然后,我们检查保存的实例状态是否不为 null。如果它不为 null,那么我们获取存储在保存的实例状态中的数据,并将该数据设置为我们的 EditText。然后,我们为 Button 添加一个 onclick 监听器。在 onclick 方法中,我们使用 EditText 中的数据显示一个 Toast 消息。然后,我们创建一个名为 onSaveInstanceState 的方法。在此方法中,我们通过使用名为“message”的键设置 EditText 中的数据来保存 EditText 的状态。我们将在 onCreate 方法中使用相同的键读取数据。
添加上述代码后,我们只需点击顶部的绿色图标即可在移动设备上运行我们的应用程序。
注意:确保已连接到您的真实设备或模拟器。
输出
结论
在本文中,我们探讨了如何在 Android 中防止自定义视图在屏幕方向改变时丢失状态。