web-dev-qa-db-ja.com

Android Navigation ComponentでnavigateUpを使用してデータ/バンドルを渡します

質問を見つけましたが、コードに解決策がありません

バックプレス/手動バックが発生したときにデータが欲しい。戻るためにnavigateUp()を使用しています。前のフラグメントにデータを渡すにはどうすればよいですか? navigateUp()には、前のフラグメントにデータを渡す機能がありません。 Safe Args を使用した解決策は見つかりませんでした。データを転送しています。後ろにFrad B-> Frag Aを入れたい。

前のフラグメントに戻るためのコード

Navigation.findNavController(view).navigateUp()

enter image description here

私の質問は、以前のフラグメントでデータを取得するにはどうすればよいですか?を使用してFrag BからFrag Aに移動できます

12
Bhavesh Hirpara

あなたは電話することができます

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

ここで、argsはバンドルです。 fragment1で、引数からデータをフェッチします

0
P.Rai

次の簡単な実装を使用して、popBackStack()の後にAndroidナビゲーションコンポーネントでデータを渡すことができます。このアプローチは公式 Googleドキュメント に基づいています

BaseFragmentでフラグメントを拡張し、次のメソッドを使用するだけです。

//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. SharedViewModelクラスを追加する

    class SharedViewModel : ViewModel() {
        val sharedData = MutableLiveData<Any>()
    
        fun share(obj: Any) {
            sharedData.value = obj
        }
    }
    
  2. 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. フラグメント1を追加

    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. フラグメント2を追加

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

乾杯;)

0
valerybodak