Custom ToolBar for each Fragment of BottomNavigationBar with Kotlin - android

Android Studio generated simple template with following MainActivity code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupBottomNavigationBar()
}
private fun setupBottomNavigationBar() {
val navView: BottomNavigationView = findViewById(R.id.bottom_nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(setOf(
R.id.navigation_profile, R.id.navigation_chats,
R.id.navigation_conferences, R.id.navigation_settings))
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
And here's activity_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"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="#color/colorPrimary"
app:itemIconTint="#color/colorPrimaryDark"
app:itemTextColor="#color/colorPrimaryDark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu" />
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#id/bottom_nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
But when I change AppTheme style parent to "Theme.AppCompat.Light.NoActionBar" the app crashes with following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.acase/com.example.acase.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.appcompat.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
It's trying to set title of fragment on nonexistent ActionBar.
So the question is how can I setup custom toolbar for each Fragment without showing default toolbar?

Related

Android Navigation Error: You must call setGraph() before calling getGraph()

I'm trying to make an memo app, and this is my first time with application programming.
When I tried to run the code on my device it just dies after showing the IntroActivity and the error log says: "You must call setGraph() before calling getGraph()"
Below is the code.
class ListActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityListBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityListBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_content_list)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
binding.fab.setOnClickListener { view ->
val intent=Intent(applicationContext, DetailActivity::class.java)
startActivity(intent)
}
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_list)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
}
When I googled about this error there were only answers about androidx.navigation version 2.3.0-alpha2, so I checked my build.gradle.
I was using 2.5.0, the latest version.
How else can I solve this problem?
activity_list.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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=".ListActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.DimoMemo.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/Theme.DimoMemo.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="#layout/content_list" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="#dimen/fab_margin"
android:layout_marginBottom="16dp"
app:srcCompat="#drawable/ic_add"
android:layout_marginRight="#dimen/fab_margin" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
content_list.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<fragment
android:id="#+id/nav_host_fragment_content_list"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp" />
</FrameLayout>
check if the layout contains:
app:navGraph="#navigation/nav_graph"
app:defaultNavHost="true"
your nav_host_fragment_content_list must look like:
<fragment
android:id="#+id/nav_host_fragment_content_list"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:navGraph="#navigation/your_nav_graph"
app:defaultNavHost="true" />
https://developer.android.com/guide/navigation/navigation-getting-started

Is it possible to centre the actionbar title from a fragment using AndroidX navigation?

Currently, I am using the Navigation component from Android and the actionbar title is displayed on the left. However, I kind of want it centralised to make things neater, is there any way to go about doing so?
Image of the actionbar title that is displayed on the left
Activity's code:
public class General extends AppCompatActivity {
private BottomNavigationView bottomNavigationView;
private NavController navController;
private AppBarConfiguration appBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.general);
bottomNavigationView = findViewById(R.id.bottomNavigationView);
navController = Navigation.findNavController(this, R.id.fragment);
appBarConfiguration = new AppBarConfiguration.Builder(R.id.addFragment, R.id.homeFragment).build();
NavigationUI.setupWithNavController(bottomNavigationView, navController);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
}
}
Activity's XML Code
<?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=".General">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
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">
</com.google.android.material.bottomnavigation.BottomNavigationView>
<fragment
android:id="#+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/bottomNavigationView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/the_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment XML Code:
<?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/the_navigation"
app:startDestination="#id/homeFragment">
<fragment
android:id="#+id/homeFragment"
android:name="com.test.HomeFragment"
android:label="Home"
tools:layout="#layout/home_fragment" />
<fragment
android:id="#+id/addFragment"
android:name="com.test.AddFragment"
android:label="Add"
tools:layout="#layout/add_fragment" />
</navigation>
After a bit of searching, it seems like this did the trick. All I had to do was to add it to my Activity code.
As the fragments are a childs of Parent activity, so we can centralize or customize the title as we want on the Parent Activity.
Here is an example how to center the title without doing the iterate for all View widgets ...
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
navView = findViewById(R.id.nav_view)
navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_settings, R.id.navigation_info
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
// Detect on where fragment we are, and custom the title from here
navController
.addOnDestinationChangedListener { nc: NavController, nd: NavDestination, args: Bundle? ->
when(nd.id){
R.id.navigation_home -> {
supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
supportActionBar?.setCustomView(R.layout.title_home_action_bar_layout)
}
R.id.navigation_settings -> {
supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
supportActionBar?.setCustomView(R.layout.title_settings_action_bar_layout)
}
R.id.navigation_info -> {
supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
supportActionBar?.setCustomView(R.layout.title_info_action_bar_layout)
}
}
}
}
For the custom centered title : title_settings_action_bar_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/tvTitle"
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Settings Baby Watcher"
android:textColor="#FFFFFF" />
</LinearLayout>

Navigation Component action won't hide the original fragment before showing the destination fragment [duplicate]

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>

Why my app seems not responding after adding fragment in my mainActivity when implementing Navigation Graph?

I am trying to learn how to use the navigation controller. and the problem is, My app seems not responding, it takes a very long time to show the main activity, and I can't also press the back button (seems not active)
here is the screenshot of my navigation graph, I am trying to set the host fragment in my Main Activity, as you can see, it seems a little bit weird that the bottom navigation view and the toolbar seem double on the NavHostFragment.
here is the screenshot of my main activity:
here is my mainActivity xml:
<android.support.constraint.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="?attr/actionBarTheme"
android:minHeight="?attr/actionBarSize"
android:id="#+id/toolbar"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<fragment
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/nav_host_fragment"
app:layout_constraintBottom_toTopOf="#+id/bottom_nav"
app:layout_constraintTop_toBottomOf="#+id/toolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/navigation_graph"
app:defaultNavHost="true"
/>
<android.support.design.widget.BottomNavigationView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#color/colorPrimary"
app:itemIconTint="#color/color_bottom_view_navigation"
app:itemTextColor="#color/color_bottom_view_navigation"
app:menu="#menu/menu_bottom_view"
app:labelVisibilityMode="labeled"
android:id="#+id/bottom_nav"/>
</android.support.constraint.ConstraintLayout>
and here is the xml of navigation 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/navigation_graph"
app:startDestination="#id/mainActivity">
<activity android:id="#+id/mainActivity" android:name="com.muchammadagunglaksana.navcontroller.MainActivity"
android:label="activity_main" tools:layout="#layout/activity_main"/>
</navigation>
and here is my MainActivity class:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navController = Navigation.findNavController(this, R.id.nav_host_fragment)
setupBottomNavMenu(navController)
setupActionBar(navController)
}
private fun setupBottomNavMenu(navController: NavController) {
bottom_nav?.let {
NavigationUI.setupWithNavController(it, navController)
}
}
private fun setupActionBar(navController: NavController) {
NavigationUI.setupActionBarWithNavController(this, navController)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_toolbar, menu)
return true
}
}
what went wrong in here?
It is because you are adding the same activity(mainActivity) as your start destination inside nav host fragment that is also part of main activity.
Solution is you have to remove main activty as your starting destination and add anotehr fragment/activity in it. like this:
<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/navigation_graph"
app:startDestination="#id/mainFragment">
<fragment android:id="#+id/mainFragment"
android:name="com.cinderellaman.general.ui.fragments.MainFragment"
android:label="main_fragment"
tools:layout="#layout/main_fragment"/></navigation>

Android architecture component navigation: toolbar back button missing, back not working

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>

Categories

Resources