Pass data/bundle using navigateUp in Android Navigation Component

前端 未结 6 1114
予麋鹿
予麋鹿 2020-12-14 09:51

I found the question but does not have solution in code

I want to have data when backpress/manual back happens. I am using navigateUp() to go back. How

6条回答
  •  粉色の甜心
    2020-12-14 10:27

    You can use the following simple implementation to pass data after popBackStack() with Android Navigation Component. This approach is based on official Google documentation

    You just need to extend your fragments with BaseFragment and use the following methods:

    //to start Fragment2 for result
    startFragmentForResult(actionId: Int)
    
    //to perform pop back stack in Fragment2
    popBackStackWithResult(result: Any)
    
    //to observe your result in Fragment1
    onFragmentResult(result: Any)
    
    1. Add SharedViewModel class

      class SharedViewModel : ViewModel() {
          val sharedData = MutableLiveData()
      
          fun share(obj: Any) {
              sharedData.value = obj
          }
      }
      
    2. Add BaseFragment class

      import androidx.fragment.app.Fragment
      
      abstract class BaseFragment : Fragment() {
      
      protected var rootView: View? = null
      
      private var sharedViewModel: SharedViewModel? = null
      
      override fun onCreateView(
          inflater: LayoutInflater,
          container: ViewGroup?,
          savedInstanceState: Bundle?
      ): View? {
          if (rootView == null) {
              rootView = inflater.inflate(getLayoutId(), container, false)
              initSharedViewModel()
          }
          return rootView
      }
      
      abstract fun getLayoutId()
      
      open fun onFragmentResult(result: Any){
          //TODO implement in descendants
      }
      
      protected fun startFragmentForResult(actionId: Int){
          findNavController().navigate(actionId)
      }
      
      protected fun popBackStackWithResult(result: Any){
          findNavController().popBackStack()
          sharedViewModel?.share(result)
      }
      
      private fun initSharedViewModel() {
          sharedViewModel = ViewModelProvider(activity!!).get(SharedViewModel::class.java)
      
          sharedViewModel?.sharedData?.observe(activity!!, object : Observer {
              override fun onChanged(params: Any) {
                  onFragmentResult(params)
              }
          })
      }    
      }
      
    3. Add Fragment1

      class Fragment1 : BaseFragment(){
          override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
              super.onViewCreated(view, savedInstanceState)
      
              some_btn.setOnClickListener{
                  startFragmentForResult(R.id.action_fragment1_to_fragment2)
              }
          }
      
          override fun onFragmentResult(result: Any) {
              if(result is AnyYourClass){
                  //PERFECT! DO SOMETHING WITH YOUR RESULT
              }
          }
      }
      
    4. Add Fragment2

      class Fragment2 : BaseFragment(){
          override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
              super.onViewCreated(view, savedInstanceState)
      
              some_btn.setOnClickListener{
                  popBackStackWithResult(AnyYourClass())
              }
          }            
      }
      

    Cheers ;)

提交回复
热议问题