当我旋转屏幕时,我从 Activity 发送到 Fragment 的包仍然存在。为什么?
The bundle i sent to Fragment from Activity is still alive when i rotate the screen. WHY?
我有一个 Activity,还有一个 TextView、一个 EditText、一个按钮和一个 FrameLayout。
我在 EditText 中输入了一些词,然后按下发送按钮,Activity 的 TextView 将随着该词发生变化,同时生成一个包含该词的包并开始一个 Fragment。
在片段的 onCreate 方法中,我可以获得刚从 Activity 发送的参数。
然后我把这个词放在 Fragment 的 TextView 中。
但是当我旋转屏幕时问题就开始了。
我了解到屏幕旋转时所有属性都会重置。
因此,Activity 的 TextView 被重置。没关系。我就知道。
但是 Fragment 的 TextView 甚至还活着!
它没有重置。
为什么?
我检查了日志。这太奇怪了。
这是App的全部订单。
2020-09-17 11:53:16.569 15207-15207/com.example.screenlotateex D/TEST: Activity onCreate()
2020-09-17 11:53:33.541 15207-15207/com.example.screenlotateex D/TEST:从 Activity
发送 Bundle
2020-09-17 11:53:33.623 15207-15207/com.example.screenlotateex D/TEST:片段 onCreate()
2020-09-17 11:53:33.623 15207-15207/com.example.screenlotateex D/TEST:从 Activity 获取 Bundle:现在正在下雨。
2020-09-17 11:53:37.331 15207-15207/com.example.screenlotateex D/TEST: Activity onPause()
2020-09-17 11:53:37.340 15207-15207/com.example.screenlotateex D/TEST: Activity onStop()
2020-09-17 11:53:37.366 15207-15207/com.example.screenlotateex D/TEST: 片段 onDestroyView()
2020-09-17 11:53:37.378 15207-15207/com.example.screenlotateex D/TEST:片段 onDestroy()
2020-09-17 11:53:37.378 15207-15207/com.example.screenlotateex D/TEST:片段 onDetach()
2020-09-17 11:53:37.381 15207-15207/com.example.screenlotateex D/TEST: Activity onDestroy()
2020-09-17 11:53:37.526 15207-15207/com.example.screenlotateex D/TEST: 片段 onCreate()
2020-09-17 11:53:37.526 15207-15207/com.example.screenlotateex D/TEST:从 Activity 获取 Bundle:现在正在下雨。
2020-09-17 11:53:37.780 15207-15207/com.example.screenlotateex D/TEST: Activity onCreate()
为什么我没有再次按下按钮时片段的onCreate 方法自动运行?
最奇怪的是片段的 onCreate 在 activity 的 onCreate 之前开始!!!
而且捆绑包还活着!好可怕。
这是我的代码。
Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("TEST", "Activity onCreate()")
button.setOnClickListener {
text.text = editText.text.toString()
val bundle = Bundle()
Log.d("TEST", "send Bundle from Activity")
bundle.putString("key", editText.text.toString())
val fragment = TestFragment()
fragment.arguments = bundle
supportFragmentManager.beginTransaction().replace(R.id.frameLayout, fragment).commit()
}
}
override fun onPause() {
super.onPause()
Log.d("TEST", "Activity onPause()")
}
override fun onStop() {
super.onStop()
Log.d("TEST", "Activity onStop()")
}
override fun onDestroy() {
super.onDestroy()
Log.d("TEST", "Activity onDestroy()")
}
}
Activity XML
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text"
android:hint="write here."/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SEND"
app:layout_constraintTop_toBottomOf="@id/editText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
片段
class TestFragment : Fragment() {
private var text: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("TEST", "Fragment onCreate()")
arguments?.let {
text = it.getString("key")
Log.d("TEST", "get Bundle from Activity : $text")
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_test, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
frag_text.text = text
}
override fun onDestroyView() {
super.onDestroyView()
Log.d("TEST", "Fragment onDestroyView()")
}
override fun onDestroy() {
super.onDestroy()
Log.d("TEST", "Fragment onDestroy()")
}
override fun onDetach() {
super.onDetach()
Log.d("TEST", "Fragment onDetach()")
}
}
片段XML
<androidx.constraintlayout.widget.ConstraintLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".TestFragment">
<TextView
android:id="@+id/frag_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_blank_fragment"
android:textColor="@color/colorAccent"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.564"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.243" />
</androidx.constraintlayout.widget.ConstraintLayout>
我真的希望有人能帮助我。
所有 Android 的核心部分是保存状态,让用户回到与旋转设备、切换到另一个应用程序并切换回来等后完全相同的状态。这是为什么 类 像 Activity 有 onSaveInstanceState()
方法。
作为此库的一部分,例如 Fragments,会自动插入这些方法。这意味着 FragmentManager 会自动保存和恢复其状态 - 包括存在的片段及其参数包。
对于片段,它们会作为对 super.onCreate()
调用的一部分进行恢复 - 如果您在 super.onCreate()
之前移动了日志消息,您会看到它 运行在片段的 onCreate()
.
之前
我有一个 Activity,还有一个 TextView、一个 EditText、一个按钮和一个 FrameLayout。 我在 EditText 中输入了一些词,然后按下发送按钮,Activity 的 TextView 将随着该词发生变化,同时生成一个包含该词的包并开始一个 Fragment。 在片段的 onCreate 方法中,我可以获得刚从 Activity 发送的参数。 然后我把这个词放在 Fragment 的 TextView 中。 但是当我旋转屏幕时问题就开始了。
我了解到屏幕旋转时所有属性都会重置。 因此,Activity 的 TextView 被重置。没关系。我就知道。 但是 Fragment 的 TextView 甚至还活着! 它没有重置。
为什么?
我检查了日志。这太奇怪了。 这是App的全部订单。
2020-09-17 11:53:16.569 15207-15207/com.example.screenlotateex D/TEST: Activity onCreate()
2020-09-17 11:53:33.541 15207-15207/com.example.screenlotateex D/TEST:从 Activity
发送 Bundle2020-09-17 11:53:33.623 15207-15207/com.example.screenlotateex D/TEST:片段 onCreate()
2020-09-17 11:53:33.623 15207-15207/com.example.screenlotateex D/TEST:从 Activity 获取 Bundle:现在正在下雨。
2020-09-17 11:53:37.331 15207-15207/com.example.screenlotateex D/TEST: Activity onPause()
2020-09-17 11:53:37.340 15207-15207/com.example.screenlotateex D/TEST: Activity onStop()
2020-09-17 11:53:37.366 15207-15207/com.example.screenlotateex D/TEST: 片段 onDestroyView()
2020-09-17 11:53:37.378 15207-15207/com.example.screenlotateex D/TEST:片段 onDestroy()
2020-09-17 11:53:37.378 15207-15207/com.example.screenlotateex D/TEST:片段 onDetach()
2020-09-17 11:53:37.381 15207-15207/com.example.screenlotateex D/TEST: Activity onDestroy()
2020-09-17 11:53:37.526 15207-15207/com.example.screenlotateex D/TEST: 片段 onCreate()
2020-09-17 11:53:37.526 15207-15207/com.example.screenlotateex D/TEST:从 Activity 获取 Bundle:现在正在下雨。
2020-09-17 11:53:37.780 15207-15207/com.example.screenlotateex D/TEST: Activity onCreate()
为什么我没有再次按下按钮时片段的onCreate 方法自动运行? 最奇怪的是片段的 onCreate 在 activity 的 onCreate 之前开始!!! 而且捆绑包还活着!好可怕。
这是我的代码。
Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("TEST", "Activity onCreate()")
button.setOnClickListener {
text.text = editText.text.toString()
val bundle = Bundle()
Log.d("TEST", "send Bundle from Activity")
bundle.putString("key", editText.text.toString())
val fragment = TestFragment()
fragment.arguments = bundle
supportFragmentManager.beginTransaction().replace(R.id.frameLayout, fragment).commit()
}
}
override fun onPause() {
super.onPause()
Log.d("TEST", "Activity onPause()")
}
override fun onStop() {
super.onStop()
Log.d("TEST", "Activity onStop()")
}
override fun onDestroy() {
super.onDestroy()
Log.d("TEST", "Activity onDestroy()")
}
}
Activity XML
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text"
android:hint="write here."/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SEND"
app:layout_constraintTop_toBottomOf="@id/editText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
片段
class TestFragment : Fragment() {
private var text: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("TEST", "Fragment onCreate()")
arguments?.let {
text = it.getString("key")
Log.d("TEST", "get Bundle from Activity : $text")
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_test, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
frag_text.text = text
}
override fun onDestroyView() {
super.onDestroyView()
Log.d("TEST", "Fragment onDestroyView()")
}
override fun onDestroy() {
super.onDestroy()
Log.d("TEST", "Fragment onDestroy()")
}
override fun onDetach() {
super.onDetach()
Log.d("TEST", "Fragment onDetach()")
}
}
片段XML
<androidx.constraintlayout.widget.ConstraintLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".TestFragment">
<TextView
android:id="@+id/frag_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_blank_fragment"
android:textColor="@color/colorAccent"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.564"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.243" />
</androidx.constraintlayout.widget.ConstraintLayout>
我真的希望有人能帮助我。
所有 Android 的核心部分是保存状态,让用户回到与旋转设备、切换到另一个应用程序并切换回来等后完全相同的状态。这是为什么 类 像 Activity 有 onSaveInstanceState()
方法。
作为此库的一部分,例如 Fragments,会自动插入这些方法。这意味着 FragmentManager 会自动保存和恢复其状态 - 包括存在的片段及其参数包。
对于片段,它们会作为对 super.onCreate()
调用的一部分进行恢复 - 如果您在 super.onCreate()
之前移动了日志消息,您会看到它 运行在片段的 onCreate()
.