[譯]Android Activity 和 Fragment 狀態(tài)保存與恢復的最佳實踐
The Real Best Practices to Save/Restore Activity's and Fragment's state. (StatedFragment is now deprecated)
代碼記錄
package com.t.hencustomeviews
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.core.widget.addTextChangedListener
import com.t.hencustomeviews.databinding.ActDataSaveBinding
class ActDataSave : AppCompatActivity() {
private lateinit var binding: ActDataSaveBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActDataSaveBinding.inflate(layoutInflater)
setContentView(binding.root)
do2()
}
//http://www.reibang.com/p/45cc7775a44b
//region 1.測試View狀態(tài)保存與恢復 do1
/**
* TODO 測試View狀態(tài)保存與恢復
* binding.tv android:freezeText 默認為false
* binding.et android:freezeText 默認為true
* 測試:屏幕旋轉
* 屏幕旋轉會導致界面重繪劣挫,先調用onDestroy再調用onCreate
* 點擊tv區(qū)域加載文字然后旋轉測試
*/
private fun do1() {
Log.e("ActDataSave", "onCreate")
binding.tv.setOnClickListener {
binding.tv.text = "sth"
binding.et.setText("sssss")
}
}
//endregion do1
//region 2.測試Activity狀態(tài)保存與恢復 do2
/**
* TODO 2.1測試Activity狀態(tài)保存與恢復
* binding.tv android:freezeText 默認為false,設置為true
* binding.et android:freezeText 默認為true
* binding.tv1 android:freezeText 默認為false
* 測試:屏幕旋轉
* 屏幕旋轉會導致界面重繪,先調用onDestroy再調用onCreate
* 點擊tv區(qū)域加載文字然后旋轉測試
* 結果:text1內容沒有保存,binding.tv1旋轉后為空
*/
private var text1 = ""
private fun do2() {
binding.tv.setOnClickListener {
text1 = "click binding textView"
binding.tv1.text = text1
binding.tv.text = text1
binding.et.setText(text1)
}
}
//View 的狀態(tài)可以被自動保存夏醉,但是 Activity 成員變量卻不行。他們將隨著 Activity 一起被銷毀涧衙。我們需要手動保存和恢復
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putSerializable("text1", text1)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
text1 = savedInstanceState.getString("text1") ?: ""
}
override fun onResume() {
super.onResume()
//should init in onResume ,after onRestoreInstanceState call
binding.tv1.text = text1
}
//endregion
//Fragment狀態(tài)保存與恢復
//一旦 Fragment 從回退棧(BackStack)中返回時肤视,View 將會被銷毀和重建。
// 這種情況屬于枢里,F(xiàn)ragment 沒有被銷毀,但 Fragment 的 View 被銷毀蹂午。
// View狀態(tài)保存與恢復遵循do1()
// 而在這種情況下只有 View 被銷毀和重建栏豺。Fragment 實例仍然在那兒,包括實例里的成員變量豆胸。所以不需要對成員變量做任何事情奥洼。
}
act_data_save.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ActDataSave">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#130f30"
android:gravity="center"
android:textColor="@color/white"
android:freezesText="true"
android:textSize="18sp"
tools:text="TextView" />
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="100dp"
android:inputType="text" />
<TextView
android:id="@+id/tv1"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#130f30"
android:gravity="center"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="TextView" />
</LinearLayout>