Navigate to fragment on FAB click (Navigation Architecture Components)

前端 未结 4 844
囚心锁ツ
囚心锁ツ 2021-01-04 10:40

I have no idea how to, using the new navigation architecture component, navigate from my main screen (with a FloatingActionButton attatched to a BottomApp

相关标签:
4条回答
  • 2021-01-04 11:05

    You could have your BottomAppBar in MainActivity and access your FloatingActionButton in your fragment as follows

    activity?.fab?.setOnClickListener { 
        /*...*/
        findNavController().navigate(R.id.action_firstFragment_to_secondFragment, mDataBundle)
    }
    

    You could hide the BottomAppBar from another activity as follows

    (activity as AppCompatActivity).supportActionBar?.hide()
    

    Make sure you .show() the BottomAppBar while returning to previous fragment

    0 讨论(0)
  • 2021-01-04 11:06

    Put it in MainActivity and setOnClickListener in onStart() of the activity and it will work fine.

    override fun onStart() {
      super.onStart()
      floatingActionButton.setOnClickListener {
        it.findNavController().navigate(R.id.yourFragment)
       }
    }
    

    Note:This solution is like and hack and better is to follow Activity LifeCycle and setUp OnClickListener when the activity is ready to interact.

    Similar question [SOLVED]

    0 讨论(0)
  • 2021-01-04 11:16

    Ran into this issue today and I found out that there is a simple and elegant solution for it.

    val navController = findNavController(R.id.navHostFragment)
    
    fabAdd.setOnClickListener {
       navController.navigate(R.id.yourFragment)
    }  
    

    This takes care of the navigation. Then you must control the visibility of your BottomAppBar inside your Activity.

    0 讨论(0)
  • 2021-01-04 11:24

    if you wanted to navigate to certain fragment (not the star one) in the beginning for some reason, and also you have to graphs for one activity, here is what I suggest: this method will start activity

    companion object {
    
            const val REQUEST_OR_CONFIRM = "request_or_confirm"
            const val IS_JUST_VIEW = "IS_JUST_VIEW"
            const val MODEL = "model"
    
            fun open(activity: Activity, isRequestOrConfirm: Boolean, isJustView: Boolean = false, model: DataModel? = null) {
                val intent = Intent(activity, HostActivity::class.java)
                intent.putExtra(REQUEST_OR_CONFIRM, isRequestOrConfirm)
                intent.putExtra(IS_JUST_VIEW, isJustView)
                intent.putExtra(MODEL, model)
                activity.startActivity(intent)
            }
        }
    

    and then in, onCreate method of Host Activity, first decide which graph to use and then pass the intent extras bundle so the start fragment can decide what to do:

    override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_purchase_nav)
            if (intent.getBooleanExtra(REQUEST_OR_CONFIRM, true)) {
                findNavController(R.id.nav_host_fragment).setGraph(R.navigation.nav_first_scenario, intent.extras)
            } else {
                findNavController(R.id.nav_host_fragment).setGraph(R.navigation.nav_second_scenario, intent.extras)
            }
        }
    

    and here's how you can decide what to do in start fragment:

    if (arguments != null && arguments!!.getBoolean(HostActivity.IS_JUST_VIEW)){
        navigateToYourDestinationFrag(arguments!!.getParcelable<DataModel>(HostActivity.MODEL))
    }
    

    and then navigate like you would do normally:

    private fun navigateToYourDestinationFrag(model: DataModel) {
            val action = StartFragmentDirections.actionStartFragmentToOtherFragment(model)
            findNavController().navigate(action)
        }
    

    here's how your graph might look in case you wanted to jump to the third fragment in the beginning

    PS: make sure you will handle back button on the third fragment, here's a solution

    UPDATE: as EpicPandaForce mentioned, you can also start activities using Navigation Components: to do that, first add the Activity to your existing graph, either by the + icon (which didn't work for me) or by manually adding in the xml:

     <activity
            android:id="@+id/secondActivity"
            tools:layout="@layout/activity_second"
            android:name="com.amin.SecondActivity" >
        </activity>
    

    you can also add arguments and use them just like you would in a fragment, with navArgs()

     <activity
            android:id="@+id/secondActivity"
            tools:layout="@layout/activity_second"
            android:name="com.amin.SecondActivity" >
            <argument
                android:name="testArgument"
                app:argType="string"
                android:defaultValue="helloWorld" />
        </activity>
    

    in koltin,here's how you would use the argument, First declare args with the type of generated class named after you activity, in this case SecondActivityArgs in top of your activity class:

    val args: SecondActivityArgsby by navArgs()
    

    and then you can use it like this:

    print(args.testArgument)
    
    0 讨论(0)
提交回复
热议问题