My version of nav is 2.4.2
My problem is that when the app goes to background the bottomNav doesn't work after re enter the app in some situations.
For example, I am in the third nav. I leave the app with the home button and if I open the app again all works correctly. But if I start to open a lot of apps and after entering my app the bottomNav doesn't work. It changes the symbol colors, but doesn't navigate. The backstacks of the current nav still work.
And here is my code to set the navigation.
MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
if(savedInstanceState == null){
setupBottomNavigationBar()
}
}
private fun setupBottomNavigationBar(){
val graphs = setOf(
R.id.firstFragment,
R.id.secondFragment,
R.id.thirdFragment,
R.id.fourthFragment,
R.id.fithFragment
)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_container) as NavHostFragment
currentNavController = navHostFragment.navController
val bottomNavigation = findViewById<BottomNavigationView>(R.id.bottom_navigation)
bottomNavigation.setupWithNavController(currentNavController)
appBarConfiguration = AppBarConfiguration(graphs)
}
activityMain.xml
<LinearLayout 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:orientation="vertical"
tools:context=".activities.MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
app:navGraph="#navigation/super_nav"
/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/bottom_nav"
app:itemIconTint="#drawable/botton_navigation_colors"
app:labelVisibilityMode="unlabeled"
app:itemIconSize="35dp"
/>
bottom_nav.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/first_navigation"
android:icon="#drawable/ic_first_black"
android:contentDescription="#string/first_desc"
android:title="#string/first_title" />
<item
android:id="#+id/second_navigation"
android:icon="#drawable/ic_second"
android:contentDescription="#string/second_desc"
android:title="#string/second_title" />
<item
android:id="#+id/third_navigation"
android:icon="#drawable/ic_third"
android:contentDescription="#string/third_desc"
android:title="#string/third_title" />
<item
android:id="#+id/fourth_navigation"
android:icon="#drawable/ic_fourth"
android:contentDescription="#string/fourth_desc"
android:title="#string/fourth_title" />
<item
android:id="#+id/fifth_navigation"
android:icon="#drawable/ic_fifth"
android:contentDescription="#string/fifth_desc"
android:title="#string/fifth_title" />
super_nav.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/super_nav"
app:startDestination="#+id/main_navigation">
<include app:graph="#navigation/first_navigation"/>
<include app:graph="#navigation/second_navigation"/>
<include app:graph="#navigation/third_navigation" />
<include app:graph="#navigation/fourth_cart_navigation" />
<include app:graph="#navigation/fifth_navigation" />
Related
I created a bottom navigation in main activity and does not show menu icon or text
I use the material library version 1.7.0
I changed the version to 1.6.1 and 1.5, but there was still a problem
I invalidate caches and the problem was not solved
I also used the clean project/rebuild project, but the problem was not solved
what is the problem?
activity_main.xml
<layout
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">
<data>
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:id="#+id/mainActivityBase"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:gravity="center"
android:textAppearance="?textAppearanceHeadline4"
android:layout_marginTop="25dp"/>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="64dp"
android:clipToPadding="false"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_movie_player"
tools:layout="#layout/fragment_home" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationMain"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_alignParentBottom="true"
android:layout_marginStart="#dimen/marginStart"
android:layout_marginEnd="#dimen/marginEnd"
android:layout_marginBottom="#dimen/marginStart"
android:elevation="8dp"
app:labelVisibilityMode="unlabeled"
app:menu="#menu/movie_player_menu"
app:itemIconSize="28dp"
app:itemRippleColor="#android:color/transparent"
/>
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
movie_player_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/homeFragment"
android:title="#string/home"
android:icon="#drawable/ic_round_home_24" />
<item android:id="#+id/searchFragment"
android:title="#string/search"
android:icon="#drawable/ic_round_search_24" />
<item android:id="#+id/profileFragment"
android:title="#string/profile"
android:icon="#drawable/ic_round_person_24" />
</menu>
Navigation components setup
private lateinit var navController: NavController
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.lifecycleOwner = this
setupBottomNavigationBar()
}
private fun setupBottomNavigationBar() {
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationMain)
val navHostFragment = supportFragmentManager.findFragmentById(
R.id.nav_host_container
) as NavHostFragment
navController = navHostFragment.navController
bottomNavigationView.setupWithNavController(navController)
appBarConfiguration = AppBarConfiguration(
setOf(R.id.homeFragment, R.id.searchFragment, R.id.profileFragment)
)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration)
}
I run it on a physical phone but the problem was still there
Update
I found the problem set windowTranslucentNavigation false and problem is solved
I am learning Kotlin, have done apps in Java before. I now have an activity with an Toolbar, NavigationView and a FragmentView. As I understand this: Fragment Tutorial, it is enough to state the Fragment in the xml file.
I have this activity_main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/navigation_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/main_app_bar_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/AppTheme.AppBarOverlay"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#android:color/holo_blue_light"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/main_navigation"
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_header"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/main_app_bar_layout"
app:menu="#menu/navigation_menu" />
<androidx.fragment.app.FragmentContainerView
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_container"
android:name="com.example.android.camerax.tflite.TestFragment"
tools:layout="#layout/fragment_test" />
</androidx.drawerlayout.widget.DrawerLayout>
This is the fragment_test.xml:
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context="com.example.android.camerax.tflite.TestFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"
android:textAlignment="center"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is the Activity:
class CameraActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var fragment: CameraActivityFragment
private lateinit var navigationDrawer: DrawerLayout
private lateinit var toolbar: Toolbar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
navigationDrawer = findViewById(R.id.navigation_container)
// Handle user consent update
toolbar = findViewById(R.id.main_toolbar)
setSupportActionBar(toolbar)
val toggle = ActionBarDrawerToggle(
this,
navigationDrawer,
toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
)
navigationDrawer.addDrawerListener(toggle)
toggle.syncState()
val navigationView: NavigationView = findViewById(R.id.main_navigation)
navigationView.setNavigationItemSelectedListener(this)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.show_recordings) {
// Start ListView
}
navigationDrawer.closeDrawer(GravityCompat.START)
return true
}
}
and here is the TestFragment.kt:
class TestFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_test, container, false)
}
companion object {
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
TestFragment().apply {
arguments = Bundle().apply {
}
}
}
}
I have tried to read the link above and also follow this: AndroidTrivia. No success and I really think this is quite basic and should work. When I run the debugger I can see that onCreateView is called in the Fragment, as it should be.
This is how it looks. Sometimes, the text blips on the screen. So seems like something is overwriting the fragment?
screenshot 1
screenshot 2
Edit
After updating the FragmentContainerView with elevation 9dp, the text is shown. But now the Toolbar is hidden, although there is a marginTop for the FragmentContainerView. Screenshot 3
There are two things I would like to suggest here.
First if possible get back to ConstraintLayout as in your last answer. It is not necessary for sure, but would recommend.
Second the blipping might be cause by the difference in elevation since the elevation of NavigationView is different.
So I suggest you add the following to your FragmentContainerView
<androidx.fragment.app.FragmentContainerView
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_container"
android:elevation="9dp"
android:name="com.example.android.camerax.tflite.TestFragment"
tools:layout="#layout/fragment_test" />
9dp since most Android Views like BottomNav etc are upto 8dp
Also would recommend to modify your fragment_test as follows and add the following
<androidx.constraintlayout.widget.ConstraintLayout 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:background="#android:color/white"
android:clickable="true"
android:focusable="true"
tools:context="com.example.android.camerax.tflite.TestFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"
android:textAlignment="center"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
While creating bottom navigation with the jetpack navigation component the code below would work for an activity
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
findViewById<BottomNavigationView>(R.id.bottom_nav).setupWithNavController(navController)
with that, while working inside with fragments you need to call .setupWithNavController and pass in the navController and all should be fine.
But in my case with a navgraph inside the fragments XML and bottom navigation specified the app build but its only stuck in the home screen.
MainFragment.kt
class MainFragment : Fragment() {
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
NavigationUI.setupWithNavController(binding.bottomNav,findNavController())
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".ui.MainFragment">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/bottom_navigation_menu" />
<fragment
android:id="#+id/main_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
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/main_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
main_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/main_gragh"
app:startDestination="#id/homeFragment">
<fragment
android:id="#+id/homeFragment"
android:name="io.github.jerrymatera.medstab.ui.home.HomeFragment"
android:label="fragment_home"
tools:layout="#layout/fragment_home" />
<fragment
android:id="#+id/appointmentFragment"
android:name="io.github.jerrymatera.medstab.ui.appointment.AppointmentFragment"
android:label="appointment_fragment"
tools:layout="#layout/appointment_fragment" />
<fragment
android:id="#+id/chatFragment"
android:name="io.github.jerrymatera.medstab.ui.chat.ChatFragment"
android:label="chat_fragment"
tools:layout="#layout/chat_fragment" />
<fragment
android:id="#+id/profileFragment"
android:name="io.github.jerrymatera.medstab.ui.profile.ProfileFragment"
android:label="profile_fragment"
tools:layout="#layout/profile_fragment" />
</navigation>
menu/bottom_navigation_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/mainFragment"
android:icon="#drawable/ic_home_24"
android:title="#string/home" />
<item
android:id="#+id/appointmentFragment"
android:enabled="true"
android:icon="#drawable/ic_date_range_24"
android:title="#string/appointments" />
<item
android:id="#+id/chatFragment"
android:enabled="true"
android:icon="#drawable/ic_chat_24"
android:title="#string/chat" />
<item
android:id="#+id/profileFragment"
android:enabled="true"
android:icon="#drawable/ic_account_box_24"
android:title="#string/profile" />
</menu>
In menu resource of NavigationView (menu/bottom_navigation_menu.xml) each item ID must be matching with fragment ID in navigation graph(main_graph.xml). By this NavigationUI will figure out mapping between item and destination and it will perform fragment transaction on item selection.
change
android:id="#+id/mainFragment"
to
android:id="#+id/homeFragment"
in menu/bottom_navigation_menu.xml
Maybe the problem is in MainFragment.kt but I don't know the exact reason
NavigationUI.setupWithNavController(binding.bottomNav,findNavController())
require BottomNavigationView and NavController
I'm trying the jetpack navigation and can't show the navigation back button when I move to a new fragment.
NavigationActivity.kt
class NavActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navigation)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val host: NavHostFragment = supportFragmentManager
.findFragmentById(R.id.navigation_graph) as NavHostFragment? ?: return
// Set up Navigation
val navController = host.navController
setupActionBarWithNavController(navController)
setupBottomNavMenu(navController)
}
private fun setupActionBarWithNavController(navController: NavController) {
setupActionBarWithNavController(this, navController)
}
private fun setupBottomNavMenu(navController: NavController) {
findViewById<BottomNavigationView>(R.id.bottom_nav_view)?.let { bottomNavView ->
NavigationUI.setupWithNavController(bottomNavView, navController)
}
}
}
activity_navigation.xml
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".views.NavActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
android:background="?attr/colorPrimary"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:layout_width="match_parent">
</androidx.appcompat.widget.Toolbar>
<fragment
android:id="#+id/navigation_graph"
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_toBottomOf="#+id/toolbar"
app:navGraph="#navigation/navigation_graph"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/menu_bottom_nav" />
navigation_graph.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"
app:startDestination="#+id/launcher_home">
<fragment
android:id="#+id/launcher_home"
android:name="com.noisyninja.androidlistpoc.views.main.MainFragment"
android:label="#string/app_name"
tools:layout="#layout/fragment_main">
<action
android:id="#+id/next_action"
app:destination="#+id/detailFragment"
app:enterAnim="#anim/slide_in_right"
app:exitAnim="#anim/slide_out_left"
app:popEnterAnim="#anim/slide_in_left"
app:popExitAnim="#anim/slide_out_right" />
</fragment>
<fragment
android:id="#+id/detailFragment"
android:name="com.noisyninja.androidlistpoc.views.detail.DetailFragment"
android:label="DetailFragment" />
</navigation>
code for navigation:
/**
* opens detail activity
*/
override fun showDetail(view: View, me: Me) {
var bundle = Bundle()
bundle.putString("key", "value")
Navigation.findNavController(view).navigate(R.id.next_action, bundle, null)
}
As above when navigation to the second fragment the toolbar goes missing entirely and doesn't show the back button.
Hitting the hardware back button also doesn't pop the detail view.
The first hit has no effect, the second hit quits the app.
Override this method in your Activity with nav_host_fragment
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
Edit: Your DetailFragment contains the line
DataBindingUtil.setContentView<FragmentDetailBinding>(requireActivity(),
R.layout.fragment_detail)
which is resetting the content of your Activity to only be your fragment_detail layout, wiping out the NavHostFragment and everything else.
You should be using DataBindingUtil.bind<FragmentDetailBinding>(view)!! instead.
Original answer (you should still do this, but the above answer is actually what solves the problem)
Your ConstraintLayout is missing quite a few constraints (your views should be a vertical chain, where every app:layout_constraintTop_toBottomOf has an alternative app:layout_constraintBottom_toTopOf on the other element, etc.).
Since you have a single set of three vertically aligned items, you don't need a ConstraintLayout - just a LinearLayout is enough:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical"
tools:context=".views.NavActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:layout_width="match_parent"/>
<fragment
android:id="#+id/navigation_graph"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:navGraph="#navigation/navigation_graph"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/menu_bottom_nav" />
</LinearLayout>
I'm trying the jetpack navigation and can't show the navigation back button when I move to a new fragment.
NavigationActivity.kt
class NavActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navigation)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val host: NavHostFragment = supportFragmentManager
.findFragmentById(R.id.navigation_graph) as NavHostFragment? ?: return
// Set up Navigation
val navController = host.navController
setupActionBarWithNavController(navController)
setupBottomNavMenu(navController)
}
private fun setupActionBarWithNavController(navController: NavController) {
setupActionBarWithNavController(this, navController)
}
private fun setupBottomNavMenu(navController: NavController) {
findViewById<BottomNavigationView>(R.id.bottom_nav_view)?.let { bottomNavView ->
NavigationUI.setupWithNavController(bottomNavView, navController)
}
}
}
activity_navigation.xml
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".views.NavActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
android:background="?attr/colorPrimary"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:layout_width="match_parent">
</androidx.appcompat.widget.Toolbar>
<fragment
android:id="#+id/navigation_graph"
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_toBottomOf="#+id/toolbar"
app:navGraph="#navigation/navigation_graph"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/menu_bottom_nav" />
navigation_graph.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"
app:startDestination="#+id/launcher_home">
<fragment
android:id="#+id/launcher_home"
android:name="com.noisyninja.androidlistpoc.views.main.MainFragment"
android:label="#string/app_name"
tools:layout="#layout/fragment_main">
<action
android:id="#+id/next_action"
app:destination="#+id/detailFragment"
app:enterAnim="#anim/slide_in_right"
app:exitAnim="#anim/slide_out_left"
app:popEnterAnim="#anim/slide_in_left"
app:popExitAnim="#anim/slide_out_right" />
</fragment>
<fragment
android:id="#+id/detailFragment"
android:name="com.noisyninja.androidlistpoc.views.detail.DetailFragment"
android:label="DetailFragment" />
</navigation>
code for navigation:
/**
* opens detail activity
*/
override fun showDetail(view: View, me: Me) {
var bundle = Bundle()
bundle.putString("key", "value")
Navigation.findNavController(view).navigate(R.id.next_action, bundle, null)
}
As above when navigation to the second fragment the toolbar goes missing entirely and doesn't show the back button.
Hitting the hardware back button also doesn't pop the detail view.
The first hit has no effect, the second hit quits the app.
Override this method in your Activity with nav_host_fragment
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
Edit: Your DetailFragment contains the line
DataBindingUtil.setContentView<FragmentDetailBinding>(requireActivity(),
R.layout.fragment_detail)
which is resetting the content of your Activity to only be your fragment_detail layout, wiping out the NavHostFragment and everything else.
You should be using DataBindingUtil.bind<FragmentDetailBinding>(view)!! instead.
Original answer (you should still do this, but the above answer is actually what solves the problem)
Your ConstraintLayout is missing quite a few constraints (your views should be a vertical chain, where every app:layout_constraintTop_toBottomOf has an alternative app:layout_constraintBottom_toTopOf on the other element, etc.).
Since you have a single set of three vertically aligned items, you don't need a ConstraintLayout - just a LinearLayout is enough:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical"
tools:context=".views.NavActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:layout_width="match_parent"/>
<fragment
android:id="#+id/navigation_graph"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:navGraph="#navigation/navigation_graph"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/menu_bottom_nav" />
</LinearLayout>