Android开发中如何在多个Fragment之间保留EditText的输入值
问题原因
onSaveInstanceState仅在系统主动销毁Fragment时触发(如配置变更、内存不足回收进程),主动使用Navigation将Fragment压入回退栈时不会触发该回调,因此你用这个方法无法保存跳转场景下的输入值。- Navigation 2.4.0及以上版本默认会销毁回退栈中Fragment的View实例,你从第三个Fragment返回第二个Fragment时,SecondFragment会重新执行
onCreateView渲染新的View布局,你此前没有将保存的ediText2变量值回写到新的EditText控件中,因此输入内容为空。
解决方法
方法1:本地变量恢复(最简单,适合单Fragment简单数据)
修改SecondFragment的onCreateView逻辑,在View创建完成后将已保存的输入值回写到EditText中即可,修改后代码如下:
// SecondFragment.kt // 类内提前定义全局变量存储输入值 private var ediText2: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { param1 = it.getString(ARG_PARAM1) param2 = it.getString(ARG_PARAM2) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_second, container, false) val et2 = view.findViewById<EditText>(R.id.et2) // 新增:恢复之前保存的输入内容 ediText2?.takeIf { it.isNotEmpty() }?.let { et2.setText(it) // 可选:将光标移动到文字末尾 et2.setSelection(it.length) } view.findViewById<Button>(R.id.btn2).setOnClickListener { ediText2 = et2.text.toString() Toast.makeText(activity?.baseContext,ediText2, Toast.LENGTH_SHORT).show() Navigation.findNavController(view).navigate(R.id.action_secondFragment_to_thirdFragment) } return view }
方法2:兼容系统销毁场景
如果需要同时兼容横竖屏切换、后台进程被回收等系统销毁场景,可以新增onSaveInstanceState逻辑,同时从savedInstanceState和本地变量读取状态,代码如下:
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) // 系统销毁前存储输入值 outState.putString("et2_input_key", ediText2) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_second, container, false) val et2 = view.findViewById<EditText>(R.id.et2) // 优先读取系统销毁保存的状态 if(savedInstanceState != null){ ediText2 = savedInstanceState.getString("et2_input_key") } // 恢复输入内容 ediText2?.takeIf { it.isNotEmpty() }?.let { et2.setText(it) } // 点击跳转逻辑和之前一致 view.findViewById<Button>(R.id.btn2).setOnClickListener { ediText2 = et2.text.toString() Toast.makeText(activity?.baseContext,ediText2, Toast.LENGTH_SHORT).show() Navigation.findNavController(view).navigate(R.id.action_secondFragment_to_thirdFragment) } return view }
方法3:ViewModel持久化(推荐,适合多页面共享数据或复杂场景)
将输入值存储在与Activity绑定的ViewModel中,ViewModel生命周期长于Fragment,回退栈中的Fragment不会导致ViewModel销毁,无需手动处理状态恢复逻辑,适合多页面联动的复杂业务。
内容的提问来源于stack exchange,提问作者Vijay A
相关产品推荐
相关产品推荐

