从StatusFragment返回后HomeFragment数据绑定失效问题排查
问题:Fragment返回后数据绑定失效,ViewModelFactory未执行
我的应用包含HomeFragment和StatusFragment两个碎片,HomeFragment通过广播接收器获取连接信息并绑定至UI。初始状态下数据绑定正常,但当用户进入StatusFragment再返回HomeFragment后,信息无法完成绑定。
更新:返回HomeFragment后,onCreateView()被调用,但HomeFragmentViewModelFactory未执行!我需要通过它向ViewModel传入新的repo对象。
已尝试的操作
- 在
onResume()中调用registerReceiver() - 为
binding.lifecycleOwner设置viewLifecycleOwner替代this - 在StatusFragment中按下返回键时调用
popBackStack()
相关代码
HomeFragment
class HomeFragment : Fragment() { private var binding: FragmentHomeBinding? = null private var connectionStatus: String? = "Offline" private var connectionType: String? = "" private lateinit var mReceiver: ConnectivityChangeBroadcastReceiver lateinit var homeFragmentViewModel: HomeFragmentViewModel lateinit var repo: Repository override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentHomeBinding.inflate(inflater, container, false) binding?.lifecycleOwner = viewLifecycleOwner repo = Repository().getInstance()!! val viewModelFactory = HomeFragmentViewModelFactory(repo) homeFragmentViewModel = ViewModelProvider(this, viewModelFactory)[HomeFragmentViewModel::class.java] binding?.homeFragmentViewModel = homeFragmentViewModel this.mReceiver = ConnectivityChangeBroadcastReceiver() mReceiver.mData.observe(this, Observer { repo.setInfo(mReceiver.getData()) homeFragmentViewModel.getConnectionInfo() }) homeFragmentViewModel.navToStatusFragment.observe(this, Observer { if (it==true){ this.findNavController().navigate(R.id.action_homeFragment_to_statusFragment) homeFragmentViewModel.doneNavigateToStatusFragment() } }) return binding?.root } override fun onStart() { super.onStart() requireActivity().registerReceiver( mReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) ) repo.setInfo(mReceiver.getData()) } override fun onStop() { super.onStop() requireActivity().unregisterReceiver(mReceiver) } }
StatusFragment
class StatusFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { requireActivity().onBackPressedDispatcher.addCallback(this){ requireActivity().supportFragmentManager.popBackStack() } return inflater.inflate(R.layout.fragment_status, container, false) } }
HomeFragmentViewModel
class HomeFragmentViewModel(private val repo: Repository?) : ViewModel() { private val viewModelJob = Job() private val _navToStatusFragment = MutableLiveData<Boolean?>() val navToStatusFragment: LiveData<Boolean?> get() = _navToStatusFragment private val _connected = MutableLiveData<String?>() val connected: LiveData<String?> get() = _connected private val _connectionType = MutableLiveData<String?>() val connectionType: LiveData<String?> get() = _connectionType init { _navToStatusFragment.value = false } var isConnected: LiveData<Boolean> = connected.map { when (it) { "Online" -> true else -> false } } fun doneNavigateToStatusFragment(){ _navToStatusFragment.value = false } fun navigateToStatusFragment(){ _navToStatusFragment.value = true } fun getConnectionInfo() { when (repo?.getInfo()?.value) { 0 -> { _connected.value = "Offline" _connectionType.value = "Check Your Connection" _connectionDetails.value = null } 1 -> { _connected.value = "Online" _connectionType.value = "Cellular" _connectionDetails.value = null } 2 -> { _connected.value = "Online" _connectionType.value = "WIFI" _connectionDetails.value = null } 3 -> { _connected.value = "Online" _connectionType.value = "VPN" _connectionDetails.value = null } } Log.d("LOGGED", "Info Checked ...") } override fun onCleared() { super.onCleared() viewModelJob.cancel() } }
内容的提问来源于stack exchange,提问作者Reza Asadian
相关产品推荐
相关产品推荐

