I just want to have my "More" menu point open a BottomSheet:
I'm using the new Android navigation component with a navigation graph, but I can't figure out where I could override the behavior.
My menu.xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/navigation_home_screen"
android:icon="#drawable/ic_add_white_24dp"
android:title="#string/title_home" />
<item
android:id="#+id/navigation_sas"
android:icon="#drawable/ic_check_white_24dp"
android:title="#string/title_activity_sa" />
<item
android:id="#+id/navigation_profile"
android:icon="#drawable/ic_close_white_24dp"
android:title="#string/title_profile" />
<item
android:id="#+id/navigation_more_menu"
android:icon="#drawable/ic_more_horiz_24"
android:title="#string/title_more_menu" />
</menu>
My 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/mobile_navigation"
app:startDestination="#id/navigation_home_screen">
<fragment
android:id="#+id/navigation_home_screen"
android:name="com.dev.solidmind.ui.HomeScreenFragment"
android:label="#string/title_home"
tools:layout="#layout/fragment_home_screen" />
<fragment
android:id="#+id/navigation_sas"
android:name="com.dev.solidmind.ui.SA_Fragment"
android:label="#string/title_activity_sa"
tools:layout="#layout/fragment_sa" />
<fragment
android:id="#+id/navigation_profile"
android:name="com.dev.solidmind.ui.ProfileFragment"
android:label="#string/title_profile"
tools:layout="#layout/fragment_profile" />
<dialog
android:id="#+id/navigation_more_menu"
android:label="#string/title_more_menu" />
</navigation>
As you can see I tried adding the more menu BottomSheet as a dialog or some other item, but nothing works.
I added everything in the set-up methods for the navigation component and thought I could override the behavior in the addOnDestinationChangedListener, but it throws an error because it tries to navigate to that menu point:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
BottomNavigationView bottomNavView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home_screen, R.id.navigation_sas, R.id.navigation_profile, R.id.navigation_more_menu)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(bottomNavView, navController);
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
if (destination.getId() == R.id.navigation_home_screen) {
Objects.requireNonNull(getSupportActionBar()).hide();
} else if (destination.getId() == R.id.navigation_more_menu) {
openBottomSheet();
} else {
Objects.requireNonNull(getSupportActionBar()).show();
}
});
}
openBottomSheet method:
public void openBottomSheet() {
View dialogView = getLayoutInflater().inflate(R.layout.main_bottom_sheet_menu, findViewById(R.id.main_root_layout), false);
BottomSheetDialog dialog = new BottomSheetDialog(this);
if (paidContentUnlocked)
adaptBottomSheetToPaidStatus(dialogView);
dialog.setContentView(dialogView);
dialog.show();
}
Can I prevent the navigation and only open my menu instead?
Without having to go back to manually managing Fragments with transactions etc...
I've been able to do by simply surrounding my <fragment> tag with a CoordinatorLayout just like below
activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<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:navGraph="#navigation/nav_graph"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<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/bottom_navigation_menu"
app:labelVisibilityMode="labeled"
/>
</LinearLayout>
MyBottomSheet
class BottomSheetFragment: BottomSheetDialogFragment(), View.OnClickListener {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = BottomSheetDialog(requireContext(), theme)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_bottom_sheet, container, false)
}
}
OR the Answer of #Naveen Rao
findViewById(R.id.nav_bottom_view).setOnNavigationItemSelectedListener {
// This is to avoid going to startDestination of opening of the BottomSheet
navController.navigate(it.itemId)
true
}
Related
Take a Bottom Navigation activity from android studio template. there are 3 fragment with 3 item in BottomNavBar (HomeFragment, DashboardFragment, NotificationsFragment) navigate to DashboardFragment from HomeFragment by a button click. after that home item click from BottomNavBar should open Homefragment. But not working as expected.
Go to DashboardFrament from HomeFrament by
textView.setOnClickListener {
findNavController().navigate(R.id.navigation_dashboard)
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navView: BottomNavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
navView.setupWithNavController(navController)
}
}
main_activity.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"
android:paddingTop="?attr/actionBarSize">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
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_activity_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#id/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>
HomeFramgent.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val textView: TextView = view.findViewById(R.id.text_home)
textView.setOnClickListener {
findNavController().navigate(R.id.navigation_dashboard)
}
}
navigation.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/mobile_navigation"
app:startDestination="#+id/navigation_home">
<fragment
android:id="#+id/navigation_home"
android:name="com.app.bottomnav.ui.home.HomeFragment"
android:label="#string/title_home"
tools:layout="#layout/fragment_home" />
<fragment
android:id="#+id/navigation_dashboard"
android:name="com.app.bottomnav.ui.dashboard.DashboardFragment"
android:label="#string/title_dashboard"
tools:layout="#layout/fragment_dashboard" />
<fragment
android:id="#+id/navigation_notifications"
android:name="com.app.bottomnav.ui.notifications.NotificationsFragment"
android:label="#string/title_notifications"
tools:layout="#layout/fragment_notifications" />
</navigation>
Whenever you are navigating to any root destination from another fragment, you should have to clear the previous stack using popUpTo option builder.
Update your code navigation code in your home fragment.
findNavController()
.navigate(R.id.navigation_dashboard,
null,
NavOptions.Builder()
.setPopUpTo(R.id.navigation_home, true)
.build()
)
I don't know what is the best solution for that problem but here is a workaround:
In your activity you add public method:
fun navigateToNavBarDestination(destinationId: Int) {
binding.navView.setSelectedItemId(destinationId)
}
And in your fragments referenced in BottomNavigationView instead calling NavController::navigate you navigate in that way, lets say to dashboard:
fun navigateToDashboard() {
(activity as? MainActivity)?.navigateToNavBarDestination(R.id.dashboard)
}
Its not the perfect solution but works.
Add these lines in your MainActivity onCreate.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home,
R.id.navigation_dashboard,
R.id.navigation_notifications
))
setupActionBarWithNavController(navController, appBarConfiguration)
I have already looked this question: FragmentContainerView using findNavController about this problem. But however I stiil couldn't solve the problem. It never opens other fragments. I thought maybe it is because of view binding but I tried to do it again without using view binding. It doesn't open still.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var navController: NavController
private lateinit var navHostFragment: NavHostFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.main_nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
binding.bottomNavigationView.setupWithNavController(navController)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.home -> {
navHostFragment.navController.popBackStack()
return true
}
}
return super.onOptionsItemSelected(item)
}
}
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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/main_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph_main" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="56dp"
app:menu="#menu/menu"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
nav_graph_main
<?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_main"
app:startDestination="#id/fragmentLibrary">
<fragment
android:id="#+id/fragmentLibrary"
android:name="com.project.biosec.FragmentLibrary"
android:label="fragment_library"
tools:layout="#layout/fragment_library" />
<fragment
android:id="#+id/fragmentTransaction"
android:name="com.project.biosec.FragmentTransaction"
android:label="fragment_transaction"
tools:layout="#layout/fragment_transaction" />
<fragment
android:id="#+id/fragmentAccount"
android:name="com.project.biosec.FragmentAccount"
android:label="fragment_account"
tools:layout="#layout/fragment_account" >
<action
android:id="#+id/action_fragmentAccount_to_changeSignatureFragment"
app:destination="#id/changeSignatureFragment" />
<action
android:id="#+id/action_fragmentAccount_to_securityFragment"
app:destination="#id/securityFragment" />
<action
android:id="#+id/action_fragmentAccount_to_helpFragment"
app:destination="#id/helpFragment" />
<action
android:id="#+id/action_fragmentAccount_to_termsFragment"
app:destination="#id/termsFragment" />
</fragment>
<fragment
android:id="#+id/changeSignatureFragment"
android:name="com.project.biosec.ChangeSignatureFragment"
android:label="fragment_change_signature"
tools:layout="#layout/fragment_change_signature" />
<fragment
android:id="#+id/securityFragment"
android:name="com.project.biosec.SecurityFragment"
android:label="fragment_security"
tools:layout="#layout/fragment_security" />
<fragment
android:id="#+id/helpFragment"
android:name="com.project.biosec.HelpFragment"
android:label="fragment_help"
tools:layout="#layout/fragment_help" />
<fragment
android:id="#+id/termsFragment"
android:name="com.project.biosec.TermsFragment"
android:label="fragment_terms"
tools:layout="#layout/fragment_terms" />
</navigation>
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/feed_fragment"
android:icon="#drawable/ic_library"
android:title="#string/library" />
<item
android:id="#+id/messages_fragment"
android:icon="#drawable/ic_assignment"
android:title="#string/transactions" />
<item
android:id="#+id/profile_fragment"
android:icon="#drawable/ic_account"
android:title="#string/account" />
</menu>
As per the Setting up bottom navigation guide:
Note: Setting up bottom navigation requires that you also set up your navigation graph and menu xml as described in Tie destinations to menu items.
That section specifically states that the android:id of your destination in your navigation graph XML file needs to match the android:id of the menu item in your menu XML file.
In your case, your navigation XML uses android:id="#+id/fragmentLibrary", android:id="#+id/fragmentTransaction", and android:id="#+id/fragmentAccount", so your menu items should change to use those same IDs.
I am trying to transition an app that I have previously made to use Navigation component with fragments instead of activities ( so I'm converting my activities to fragments so they work with the component and also because it's nicer this way) and I have a problem with the Toolbar always getting pulled down a little bit without any aparent reason. I tried changing the layout roots from LinearLayout to ConstraintLayout, back again, fidgeting with android:fitsSystemWindows both for the activity layout and for the fragment one as true or false, also with views layout_height but no luck so far...
The activity looks like this:
here are my files:
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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
android:orientation="vertical">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/myNavHostFragment"
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/navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val baseAppState by inject<BaseAppStateManager>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.myNavHostFragment) as NavHostFragment
val navController = navHostFragment.navController
NavigationUI.setupActionBarWithNavController(this, navController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.myNavHostFragment)
return navController.navigateUp()
}
}
fragment_devices.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
android:orientation="vertical">
<include
android:id="#+id/dashboard_status"
layout="#layout/dashboard_phone_status"
android:layout_width="match_parent"
android:layout_height="160dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/devices_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
DevicesFragment.kt
class DevicesFragment : Fragment() {
...
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, sis: Bundle?): View {
binding = FragmentDevicesBinding.inflate(inflater, container, false)
phoneStatusScreen = PhoneStatusScreenManager(binding.dashboardStatus)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setHasOptionsMenu(true)
observeLiveData()
...viewmodel calls...
historyAdapter = DevicesHistoryAdapter(onDeviceClicked = ::onDeviceClicked)
setupRecyclerView(historyAdapter)
}
Sometimes the toolbar looks okay when I open the app but as soon as I navigate to another fragment by clicking on an element from the RecyclerView, when I click on the back arrow to navigate up, the toolbar is like you see in the screenshot below.
Also, here is the application theme:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Theme customization. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
</resources>
I am using jetpack navigation in two different activities each with its navigation host. I have Main activity which everything just works fine and Setup activity which have 2 fragments, one has a button which should navigate to other fragment when clicked .
The activity's code is as follows:
class SetupActivity : AppCompatActivity() {
private val navController by lazy { findNavController(R.id.nav_host_fragment) }
private lateinit var appBarConfig: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DataBindingUtil.setContentView<ActivitySetupBinding>(this, R.layout.activity_setup)
setSupportActionBar(toolbar)
appBarConfig = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfig)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfig) || super.onSupportNavigateUp()
}
}
Below is activity's 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".ui.SetupActivity"
tools:showIn="#layout/activity_setup">
<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_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/setup" />
</androidx.constraintlayout.widget.ConstraintLayout>
Below is code of first fragment which is also a start Destination
class ConfirmClassFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentConfirmClassBinding.inflate(inflater, container, false)
binding.fragment = this
return binding.root
}
fun navigate() {
toast("clicked") //this get called
val direction = ConfirmClassFragmentDirections.actionConfirmToSetup()
findNavController().navigate(direction) //THE PROBLEM IS HERE
//findNavController().navigate(R.id.setup)
}
}
I am using data binding to call fun navigate() as below:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="fragment"
type="com.nux.ui.fragments.ConfirmClassFragment" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="#dimen/spacing_middle">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="#{() -> fragment.navigate()}"
android:text="#string/continue_" />
</LinearLayout>
</layout>
and this how navigation xml looks like:
<?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/setup"
app:startDestination="#id/confirm">
<fragment
android:id="#+id/setup"
android:name="com.nux.ui.fragments.SetInfoFragment"
android:label="#string/setup"
tools:layout="#layout/fragment_set_info" />
<fragment
android:id="#+id/confirm"
android:name="com.nux.ui.fragments.ConfirmClassFragment"
android:label="#string/data_confirmation"
tools:layout="#layout/fragment_confirm_class">
<action
android:id="#+id/action_confirm_to_setup"
app:destination="#id/setup" />
</fragment>
</navigation>
When I click button fun gets called but nothing happens! What could be wrong?
From the code i can see you have the same id for 3 elements in the navigation graph.
#id/setup should only be used once and please change the name of the navigation graph from setup to something else.
I'm using the following activity layout with a fragment and a BottomNavigationView:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="#+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/navigation_bottom"
app:defaultNavHost="true"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/bottom_navigation_view"
app:menu="#menu/bottom_navigation_menu"/>
</LinearLayout>
And have defined three fragments in my navigation layout:
<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_bottom"
app:startDestination="#id/firstFragment">
<fragment
android:id="#+id/firstFragment"
android:name="fragments.FirstFragment"
android:label="fragment_first"
tools:layout="#layout/fragment_first" />
//The other two fragments
</navigation>
Inside my activity, I'm using the following code:
navController = Navigation.findNavController(this, R.id.fragment);
BottomNavigationView bnw = findViewById(R.id.bottom_navigation_view);
NavigationUI.setupWithNavController(bnw, navController);
NavigationUI.setupActionBarWithNavController(this, navController);
And this my onSupportNavigateUp method:
#Override
public boolean onSupportNavigateUp() {
return Navigation.findNavController(this, R.id.fragment).navigateUp();
}
But when I press on the second icon (fragment) nothing happens. How to solve this issue? Thanks!
Solution 1:
In your menu(bottom_navigation_menu) item set same id as your fragment id generated by navigation graph like below:
<menu xmlns:android="http://schemas.android.com. /apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/firstFragment"
android:title="First fragment" />
<item
android:id="#+id/secondFragment"
android:title="Second fragmnet" />
<item
android:id="#+id/thirdFragment"
android:title="Third fragment" />
</menu>
You don't need to set by pro-grammatically because
NavigationUI.setupWithNavController(bnw, navController);
method will do the job.
Solution 2: Not recomended and Un-necessary
But if you want pro-grammatically then do like below:
private lateinit var navController: NavController
private val onNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_home -> {
navController.navigate(R.id.firstFragment)
return#OnNavigationItemSelectedListener true
}
R.id.navigation_dashboard -> {
navController.navigate(R.id.secondFragment)
return#OnNavigationItemSelectedListener true
}
R.id.navigation_notifications -> {
Toast.makeText(this,R.string.title_notifications,Toast.LENGTH_SHORT).show()
navController.navigate(R.id.thirdFragment)
return#OnNavigationItemSelectedListener true
}
}
false
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
navController = findNavController(R.id.nav_controller_fragment)
navView.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener)
}