web-dev-qa-db-fra.com

Transférer des données / bundle en utilisant navigUp dans Android Composant de navigation

J'ai trouvé la question mais n'a pas de solution dans le code

Je veux avoir des données lorsque le backpress/back manuel se produit. J'utilise navigateUp() pour revenir en arrière. Comment puis-je transmettre des données au fragment précédent? navigateUp() n'a pas la possibilité de transmettre des données au fragment précédent. Même moi, je n'ai pas trouvé de solution en utilisant Safe Args . Il transmet des données. Je veux avoir en arrière Frad B -> Frag A.

Mon code pour revenir au fragment précédent

Navigation.findNavController(view).navigateUp()

enter image description here

Ma question est, comment puis-je obtenir des données dans le fragment précédent. Je peux naviguer vers Frag A depuis Frag B en utilisant

12
Bhavesh Hirpara

Vous pouvez simplement appeler

findNavController().navigate(R.id.fragment1, args)

où args est votre paquet. Dans fragment1, récupérez les données des arguments

0
P.Rai

Vous pouvez utiliser l'implémentation simple suivante pour transmettre des données après popBackStack () avec Composant de navigation Android . Cette approche est basée sur des informations officielles documentation Google

Il vous suffit d'étendre vos fragments avec BaseFragment et d'utiliser les méthodes suivantes:

//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. Ajouter une classe SharedViewModel

    class SharedViewModel : ViewModel() {
        val sharedData = MutableLiveData<Any>()
    
        fun share(obj: Any) {
            sharedData.value = obj
        }
    }
    
  2. Ajouter la classe BaseFragment

    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<Any> {
            override fun onChanged(params: Any) {
                onPopBackStackResult(params)
            }
        })
    }    
    }
    
  3. Ajouter un 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. Ajouter un fragment2

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

À votre santé ;)

0
valerybodak