I just set up a projet with Android navigation component and here's the structure of my graph:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/nav_graph"
app:startDestination="#id/a">
<fragment
android:id="#+id/a"
android:name="com.example.tutorial.fragmentA"
android:label="a">
<action android:id="#+id/action_a_to_b"
app:destination="#id/b"
app:enterAnim="#anim/nav_default_enter_anim"
app:exitAnim="#anim/nav_default_exit_anim"
app:popEnterAnim="#anim/nav_default_pop_enter_anim"
app:popExitAnim="#anim/nav_default_pop_exit_anim"/>
</fragment>
<fragment
android:id="#+id/b"
android:name="com.example.tutorial.fragmentB"
android:label="b">
</fragment>
</navigation>
In fragment A I navigate to B like this:
findNavController().navigate(R.id.action_a_to_b)
In fragment B, I have a custom toolbar and the idea is that a click on the top left arrow should close fragment B and resume A:
(activity as AppCompatActivity).setSupportActionBar(binding.toolbar)
binding.toolbar.setNavigationOnClickListener {
findNavController().popBackStack()
}
Same goes if I click on the Key down press button:
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner){
findNavController().popBackStack()
}
The problem I'm still stuck in fragment B: the exit animation starts and ends and I'm still in fragment B. Any ideas how to go about to fix this ?
I've created a small project with 2 fragments and it works flowless.
We have a login Screen and a screen with passwords.
LoginFragment
class LoginFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_login, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val toolbar = view.findViewById<androidx.appcompat.widget.Toolbar>(R.id.loginToolbar)
toolbar.navigationIcon = null
// Set the Toolbar as your activity's ActionBar
(requireActivity() as AppCompatActivity).setSupportActionBar(toolbar)
// Find this Fragment's NavController
val navController = NavHostFragment.findNavController(this);
// And set up the ActionBar
NavigationUI.setupActionBarWithNavController(
requireActivity() as AppCompatActivity,
navController
)
val b = view.findViewById<MaterialButton>(R.id.loginButton)
b.setOnClickListener {
this.findNavController().navigate(R.id.passwordsFragment)
}
}
}
PasswordFragment
class PasswordsFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_passwords, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val toolbar = view.findViewById<androidx.appcompat.widget.Toolbar>(R.id.myToolbar)
// Set the Toolbar as your activity's ActionBar
(requireActivity() as AppCompatActivity).setSupportActionBar(toolbar)
// Find this Fragment's NavController
val navController = NavHostFragment.findNavController(this);
// And set up the ActionBar
NavigationUI.setupActionBarWithNavController(
requireActivity() as AppCompatActivity,
navController
)
toolbar.setNavigationOnClickListener {
navController.navigateUp()
}
}
}
Toolbar in the LoginFragment XML
<androidx.appcompat.widget.Toolbar
android:id="#+id/loginToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black"
app:layout_constraintTop_toTopOf="parent" />
Toolbar in the PasswordFragment XML
<androidx.appcompat.widget.Toolbar
android:id="#+id/myToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black"
app:layout_constraintTop_toTopOf="parent" />
MainActivity XML
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/constraintLayout3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="6dp"
android:fillViewport="true"
android:orientation="vertical">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
I navigate from the loginFragment to the PasswordFragment and then I press the up button and I get to the previous fragment :)
Let me know if it works
private lateinit var appBarConfiguration: AppBarConfiguration
//onCreate
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.fragment4) as NavHostFragment
val navController = navHostFragment.navController
appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navDrawView.setupWithNavController(navController)
bottomAppBar.background = null
bottomAppBar.setupWithNavController(navController)
//automatic NavigateUp setup
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.fragment4)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
Can you try this setup in your main activity, it's worked for me I use bottomNav navdrawer and appbar together.
if you wanna use custom Toolbar
//in fragment or activity
private fun handleToolbarChanges() {
with(binding.toolbarDataAnalysis) {
setNavigationOnClickListener { onBackPressed() }
title = "your title here"
}
}
//in xml file
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbarDataAnalysis"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/green"
app:navigationIcon="#drawable/ic_baseline_arrow_back_24"
app:titleTextColor="#color/white" />
Now its possible we can create observer for return values from second fragment using popBackStack()
Suppose we have firstFragment and secondFragment
In firstFragment use this for observer :-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val navController = findNavController()
navController.currentBackStackEntry?.savedStateHandle?.getLiveData<String>("isDelete")
?.observe(viewLifecycleOwner) {
if(it.lowercase().compareTo("true")==0)
{
//write code here
}
else
{
//write code here
}
}
}
In secondFragment use this code
val navController = findNavController()
navController.previousBackStackEntry?.savedStateHandle?.set("isDelete", "true/false")
navController.popBackStack()
Related
I'm using Navigation Component with Kotlin, and have three main tabs in nav_dashboard - Explore, My Groups and Profile. When I start application the startDestination is nav_explore, but then I want to go from there to different screens eg. CreateGroupFragment/nav_create_group and from there I have button that I want to redirect me to nav_dashboard but with My Groups selected - I guess that then the startDestination needs to be nav_profile. But how I can I implement that?
Dashboard Fragment (it contains Fragment Container View in XML):
internal class DashboardFragment : Fragment() {
lateinit var navigator: DashboardNavigator
private var _binding: FragmentDashboardBinding? = null
private val binding
get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentDashboardBinding.inflate(layoutInflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initBottomNavigation()
}
private fun initBottomNavigation() {
with(binding.bottomNavigationView) {
setupWithNavController(getDashboardNestedNavController())
}
}
private fun getDashboardNestedNavController(): NavController {
val navHostFragment = childFragmentManager.findFragmentById(R.id.nav_host_container) as NavHostFragment
val navGraph = navHostFragment.navController.navInflater.inflate(R.navigation.nav_dashboard_menu)
navHostFragment.navController.addOnDestinationChangedListener { _, destination, bundle ->
when (destination.id) {
R.id.exploreFragment, R.id.myGroupsFragment, R.id.profileFragment -> setBottomNavVisibility(View.VISIBLE)
else -> setBottomNavVisibility(View.GONE)
}
}
return navHostFragment.navController
}
private fun setBottomNavVisibility(visibility: Int) {
binding.bottomNavigationView.visibility = visibility
}
}
nav_dashboard:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/nav_dashboard_menu"
app:startDestination="#id/nav_explore">
<include app:graph="#navigation/nav_explore" />
<include app:graph="#navigation/nav_my_groups" />
<include app:graph="#navigation/nav_profile" />
</navigation>
nav_create_group:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/nav_create_group"
app:startDestination="#id/createGroupFragment">
<include app:graph="#navigation/nav_create_group_map" />
<include app:graph="#navigation/nav_my_groups" />
<fragment
android:id="#+id/createGroupFragment"
android:name="com.wojciechkula.locals.presentation.creategroup.CreateGroupFragment"
android:label="#string/create_group_create_group"
tools:layout="#layout/fragment_create_group">
<action
android:id="#+id/openMap"
app:destination="#id/nav_create_group_map" />
<!-- Here I want another action to navigate to nav_dashboard with startDestination: nav_my_groups-->
</fragment>
</navigation>
First of all, you don't need to change the startDestination.
Secondly, why are you using multiple graphs? That usually makes things more complicated!
Anyway, you can just set the selected tab manually.
binding.bottomNavigationView.menu.findItem(R.id.tabId).isChecked = true
"tabId" is the id of the item in your bottom nav xml file.
I am wondering if there is a way to add another fragment to the screen without replacing the old one with the Navigation Graph.
I want to do this because the new fragment will just be open for a bit just to check some details and when the user returns to the previous fragment, I want them to be in the same spot they left off.
I have read around but I couldn't find one that does it without replacing the original. I have tried to just add it to the nav_graph_fragment which I try to do this in the newFrag() function in the CurrentFragment section but it doesn't work.
Main Activty
class MainActivity : AppCompatActivity() {
private lateinit var toolbar: Toolbar
private val navController by lazy {
(supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController
}
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
toolbar = findViewById(R.id.mainToolBar)
setSupportActionBar(toolbar)
appBarConfiguration = AppBarConfiguration(navController.graph, null)
setupActionBarWithNavController(navController, appBarConfiguration)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.main_menu_bar, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
if (item.itemId == navController.currentDestination?.id)
return true
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
}
}
Main Activity xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<include
layout="#layout/appbar"
android:id="#+id/mainToolBar"/>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/mainToolBar"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
CurrentFragment
class CurrentFragment : Fragment() {
private lateinit var currentFragmentViewModel: CurrentFragmentViewModel
private lateinit var binding: CurrentFragmentBinding
private lateinit var recyclerView: RecyclerView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.current_fragment, container, false)
currentFragmentViewModel = ViewModelProvider(this).get(CurrentFragmentViewModel::class.java)
binding.lifecycleOwner = this
binding.viewmodel = currentFragmentViewModel
binding.accountButton.setOnClickListener {
Log.d("TEST", "button clicked")
newFrag()
}
return binding.root
}
// Here is where I am trying to open the new fragment
private fun newFrag() {
val newFrag = Fragment()
val transaction: FragmentTransaction = parentFragmentManager.beginTransaction()
transaction.hide(this)
transaction.add(R.id.nav_host_fragment, newFrag).commit()
}
}
Nav Graph
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/nav_graph"
app:startDestination="#id/mainFragment">
<fragment
android:id="#+id/mainFragment"
android:name="com.example.app.ui.main.MainFragment"
android:label="MainFragment">
<action
android:id="#+id/action_mainFragment_to_currentFragment"
app:destination="#id/currentFragment" />
</fragment>
<fragment
android:id="#+id/currentFragment"
android:name="com.example.app.ui.search.CurrentFragment"
android:label="currentFragment" >
</fragment>
I want to use Navigation component in my fragment.
My XML code like this
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragment_nav_host_home"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:navGraph="#navigation/home_navigation"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/app_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
And Initializing navigation code like this.
class HomeFragment : Fragment() {
//...initialie view
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val navController = Navigation.findNavController(binding.fragmentNavHostHome)
navController.setGraph(R.navigation.home_navigation)
val appBarConfiguration = AppBarConfiguration(navController.graph)
NavigationUI.setupActionBarWithNavController(requireActivity() as AppCompatActivity, navController, appBarConfiguration)
}
}
And after I launched my app, I got an error message like this.
View androidx.fragment.app.FragmentContainerView{... app:id/fragment_nav_host_home} does not have a NavController set
Also, findNavController() does not work.
How can I use navigation component in my fragment
Kotlin Answer
Key point is that try to use childFragmentManager in onViewCreated() function.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Define container.
val loginDialogContainer = childFragmentManager.findFragmentById(R.id.container) as NavHostFragment
// Set nav controller.
val loginNavController: NavController = loginDialogContainer.navController
}
Iv been stuck in trying to add the Navigation Component to my app. Specifically to my toolbar menu items.
I have been following the navigation migrate documentation on Android's site but I am getting a but confused on how it works or even to set it up.
This is a single-activity multi-fragment architecture.
The app would start in the MainFragment and then when tapping the menu items in the toolbar, such as Main Frag to Search Movie Frag. The user would be able to navigate using the menu items from anywhere in the app (e.g. if they click the home icon, they should be sent to the home screen form anywhere in the app. Still thinking if thats how it should be done).
The main thing is I don't know how to properly attach the Navigation Component to the menu items.
App
Nav Graph
nav_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/nav_graph"
app:startDestination="#id/mainFragment">
<fragment
android:id="#+id/mainFragment"
android:name="com.example.movieapp.ui.main.MainFragment"
android:label="MainFragment">
<action
android:id="#+id/action_mainFragment_to_searchMovieFragment"
app:destination="#id/searchMovieFragment" />
</fragment>
<fragment
android:id="#+id/searchMovieFragment"
android:name="com.example.movieapp.ui.search.SearchMovieFragment"
android:label="SearchMovieFragment" />
</navigation>
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<include
layout="#layout/appbar"
android:id="#+id/mainToolBar"/>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/mainToolBar"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var toolbar: Toolbar
private val navController by lazy {
(supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController
}
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
toolbar = findViewById(R.id.mainToolBar)
setSupportActionBar(toolbar)
appBarConfiguration = AppBarConfiguration(navController.graph, null)
setupActionBarWithNavController(navController, appBarConfiguration)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.main_menu_bar, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
MainFragment.kt
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
private lateinit var binding: MainFragmentBinding
private lateinit var navController: NavController
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = DataBindingUtil.inflate(inflater, R.layout.main_fragment, container, false)
setHasOptionsMenu(true)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
// navController.navigate(R.id.action_mainFragment_to_searchMovieFragment)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
binding.viewModel = viewModel
// TODO: Use the ViewModel
}
}
main_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.example.movieapp.ui.main.MainViewModel" />
</data>
<LinearLayout
android:orientation="vertical"
android:id="#+id/main_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainFragment">
<TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MainFragment1" />
</LinearLayout>
</layout>
The id for a menu item in your file main_menu_bar.xml needs to match the id for the destination(fragment) specified in your navigation graph (nav_graph.xml).
Your main_menu_bar.xml should look something like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="#id/searchMovieFragment"
android:icon="#drawable/search"
android:title="#string/menu_search" />
<item
android:id="#id/mainFragment"
android:icon="#drawable/ic_menu_camera"
android:title="#string/menu_home" />
</group>
</menu>
Also, you need to override the onOptionsItemSelected(MenuItem) method and associate your menu items with destinations. Like so:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
}
Reference
You can add a Toolbar on top of the most basic FragmentContainerView, access this toolbar from other fragments, and change the toolbar I created separately according to the fragment in it while opening the relevant fragment as follows.
toolbar = requireActivity().findViewById(R.id.toolbar_base)
toolbar?.menu?.clear()
toolbar?.title = ""
val toolbarFlowFragment = context?.let { getInflateLayout(it, R.layout.toolbar_profile) }
toolbar?.addView(toolbarFlowFragment)
I switch fragments by navigation. I decided to add welcome screen with fragment to my app. I made welcome fragment as home fragment, so app starts with welcome fragment. After the welcome, I need to automatically switch to another fragment and destroy the starting fragment so that it can no longer be returned.But when fragment switches,the welcome fragment is visible under the new fragment. I solved it by android:background="?android:windowBackground". Now the new fragment overlaps the welcome fragment, but the welcome fragment still remains under the new fragment, and when I press the back arrow on the device, the welcome fragment appears again.I also removed the toolbar from the welcome fragment, and when the fragment switches, I show the toolbar, but the toolbar from the welcome fragment is displayed on the new fragment.Help my please. How to destroy welcome fragment and never come back to him?
This is main Activity
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_food_text_analysis, R.id.nav_recipe_analysis,R.id.welcome_fragment), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
This is MainActivity xml file
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer_layout"
android:fitsSystemWindows="true"
tools:context=".MainActivity"
tools:openDrawer="start">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/toolbar_background"/>
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph = "#navigation/mobile_navigation"
app:defaultNavHost="true"
/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_gravity="start"
app:headerLayout="#layout/layout_header_main"
app:menu="#menu/activiy_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
This is Welcome Fragment
private lateinit var topAnimation: Animation
private lateinit var bottomAnimation: Animation
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_welcome_screen, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(activity as AppCompatActivity).supportActionBar?.hide()
topAnimation = AnimationUtils.loadAnimation(activity, R.anim.top_animation)
bottomAnimation = AnimationUtils.loadAnimation(activity, R.anim.bottom_animation)
image_diet_girl.animation = topAnimation
welcome_text.animation = bottomAnimation
Handler().postDelayed({
(activity as AppCompatActivity).supportFragmentManager
.beginTransaction()
.setCustomAnimations(
R.anim.enter_from_right,
R.anim.exit_to_right
)
.replace(R.id.nav_host_fragment, FoodAnalysisFragment())
.commit()
},6000)
}
}
Navigation xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mobile_navigation"
app:startDestination="#id/welcome_fragment">
<fragment
android:id="#+id/nav_food_text_analysis"
android:name="com.example.nutritionfacts.ui.foodTextAnalysis.FoodAnalysisFragment"
android:label="Food analysis"
tools:layout="#layout/fragment_food_text_analysis" />
<fragment
android:id="#+id/nav_recipe_analysis"
android:name="com.example.nutritionfacts.ui.recipeAnalysis.RecipeAnalysis"
android:label="Recipe analysis"
tools:layout="#layout/fragment_recipe_analysis" />
<fragment
android:id="#+id/welcome_fragment"
android:name="com.example.nutritionfacts.ui.welcomeScreen.WelcomeScreen"
android:label="welcome screen"
tools:layout="#layout/fragment_welcome_screen" />
</navigation>