I've been trying to figure out how the default Navigation Drawer Activity template came with Android Studio navigates between different fragments. I understand that this menu is an implementation using AndroidX navigation component and navigation graph, but I just cannot understand how each menu item is mapped to its corresponding fragment. I don't see any listener or onNavigationItemSelected() etc. Can someone explain how the mapping between menuItem and corresponding fragment was achieved?
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
mAppBarConfiguration = new AppBarConfiguration.Builder(
navController.getGraph())
.setDrawerLayout(drawer)
.build();
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
}
menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
>
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_home"
android:icon="#drawable/ic_menu_camera"
android:title="#string/menu_home" />
<item
android:id="#+id/nav_gallery"
android:icon="#drawable/ic_menu_gallery"
android:title="#string/menu_gallery" />
<item
android:id="#+id/nav_slideshow"
android:icon="#drawable/ic_menu_slideshow"
android:title="#string/menu_slideshow" />
</group>
</menu>
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/mobile_navigation"
app:startDestination="#+id/nav_home">
<fragment
android:id="#+id/nav_home"
android:name="com.buzzz.myapplication.ui.home.HomeFragment"
android:label="#string/menu_home"
tools:layout="#layout/fragment_home">
<action
android:id="#+id/action_HomeFragment_to_HomeSecondFragment"
app:destination="#id/nav_home_second" />
</fragment>
<fragment
android:id="#+id/nav_home_second"
android:name="com.buzzz.myapplication.ui.home.HomeSecondFragment"
android:label="#string/home_second"
tools:layout="#layout/fragment_home_second">
<action
android:id="#+id/action_HomeSecondFragment_to_HomeFragment"
app:destination="#id/nav_home" />
<argument
android:name="myArg"
app:argType="string" />
</fragment>
<fragment
android:id="#+id/nav_gallery"
android:name="com.buzzz.myapplication.ui.gallery.GalleryFragment"
android:label="#string/menu_gallery"
tools:layout="#layout/fragment_gallery" />
<fragment
android:id="#+id/nav_slideshow"
android:name="com.buzzz.myapplication.ui.slideshow.SlideshowFragment"
android:label="#string/menu_slideshow"
tools:layout="#layout/fragment_slideshow" />
</navigation>
Thank you very much.
As per the Update UI components with NavigationUI documentation, the setupWithNavController() methods hook up UI elements (such as your NavigationView) with the NavController.
Looking at the setupWithNavController() Javadoc:
Sets up a NavigationView for use with a NavController. This will call onNavDestinationSelected when a menu item is selected. The selected item in the NavigationView will automatically be updated when the destination changes.
So internally, this is setting up the appropriate listeners - both on the NavigationView to handle menu selections and on the NavController to update the selected item when the current destination changes.
Looking at the onNavDestinationSelected() Javadoc, it becomes clear how the menu items and navigation graph destinations are matched:
Importantly, it assumes the menu item id matches a valid action id or destination id to be navigated to.
So clicking on a menu item with android:id="#+id/nav_home" will navigate to the destination with android:id="#+id/nav_home".
Related
I am working with Android Studio and I have a side menu, most of the options are working because I configure them in "mobile_navigation".
But I need one of my items to open a URL and I don't know how to do it.
My menu xml is:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_profile"
android:icon="#drawable/profile"
android:title="#string/menu_profile" />
<item
android:id="#+id/nav_web"
android:icon="#drawable/web"
android:title="#string/menu_web" />
</group>
I handle the actions of the items like this:
<fragment
android:id="#+id/nav_profile"
android:name="com.myApp.myApp.ui.profile.ProfileFragment"
android:label="#string/menu_profile"
tools:layout="#layout/fragment_profile">
<action
android:id="#+id/action_nav_profile_to_nav_fragment2"
app:destination="#id/nav_correccion" />
</fragment>
<fragment
android:id="#+id/nav_web">
</fragment>
Tried using onOptionsItemSelected (), but it still doesn't work for me. Please help
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{
private AppBarConfiguration mAppBarConfiguration;
private SharedPreferences preferences;
private DrawerLayout drawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
//navigationView.setNavigationItemSelectedListener(this);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_perfil, R.id.nav_web
)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main_drawer, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id= item.getItemId();
FragmentManager fragmentManager= getSupportFragmentManager();
if(id==R.id.nav_web){
Uri uri=Uri.parse("https://google.com.co");
Intent intent=new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);
}
DrawerLayout drawerLayout =(DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
As per the Tie destinations to menu items section, Navigation uses the IDs you add to your menu xml, matching them to destinations in your navigation graph xml file.
So if you had a menu item such as
<item
android:id="#+id/nav_web"
android:icon="#drawable/web"
android:title="#string/menu_web" />
and wanted it to start a different activity, you could add an <activity> destination to your navigation graph:
<activity
android:id="#+id/nav_web"
app:data="https://google.com.co"
app:action="android.intent.action.VIEW" />
And because they have the same ID, your activity would be started when you click that item in your menu.
I'm trying to follow this: https://developer.android.com/guide/navigation/navigation-ui along with a review of https://codelabs.developers.google.com/codelabs/android-navigation/#8 (although the second link is in Kotlin and I'm coding in Javascript) to implement an App in Android with navigation drawer on the left and a settings button (preferences) on the top right.
I'm using the NavigationUI with fragments for each option from the drawer and the settings.
My problem is that my settings fragment is not appearing. I think I'm nearly there, but despite reviewing several articles and questions cannot get it to work.
This code allows me to switch fragment from the nav drawer:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
//NavigationUI.setupWithNavController(toolbar, navController, mAppBarConfiguration);
}
If I switch the commented code on the last two lines (so I execute the last line but not second to last), to match the guide then the switching of fragment fails.
My code to handle the Settings menu is:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.onNavDestinationSelected(item, navController)
|| super.onOptionsItemSelected(item);
/*
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
// TODO: Do something to accept settings
View contextView = findViewById(R.id.nav_host_fragment); // Apparently any layout can be used
Snackbar.make(contextView, "Settings", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
//changeFragment(new SettingsFragment());
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.nav_host_fragment, new SettingsFragment(), "nh")
.addToBackStack("nh")
.commit();
return true;
}
return super.onOptionsItemSelected(item);
*/
}
The active portion matches the guide above, is getting called (proved by setting a breakpoint) but doing nothing.
If I alternatively switch this for the commented out code instead, then my settings fragment does appear but overlays the current fragment. I understand from another answer that this is because I am using two different methods to handle fragment visibility, which makes sense and is why I am trying to get my settings fragment to be handled by the NavigationUI framework.
I feel that it must be quite simple to cure, but having read and re-read the guide (and lots of answers cannot make it work)
You have different options:
Just define the SettingsFragment in your navigation graph:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--Your fragments-->
<!--Settings fragment-->
<fragment
android:id="#+id/settingsFragment"
android:name=".SettingsFragment"/>
</navigation>
Then inflate your menu with:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
In your menu use the same id used in the graph:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/settingsFragment"
.../>
</menu>
Finally override the onOptionsItemSelected method:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.onNavDestinationSelected(item, navController)
|| super.onOptionsItemSelected(item);
}
You can also define a Global Action.
<?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">
<!--Global action-->
<action android:id="#+id/action_global_open_settings_fragment"
app:destination="#id/settingsFragment"/>
</navigation>
Then in your code to navigate to a destination just use:
Navigation.findNavController(view).navigate(R.id.action_global_open_settings_fragment);
I'm not sure if I understand your problem well. But here is my solution and I hope it helps you.
Here is my Navigation Graph
And this is the Code. As you see I've an action in SettingsFragment:
<fragment
android:id="#+id/settingsFragment"
android:name="packageName.SettingsFragment"
android:label="Settings Fragment">
<action
android:id="#+id/actionSettingsToPassword"
app:destination="#id/passwordDialogFragment"
app:enterAnim="#anim/fragment_open_enter"
app:exitAnim="#anim/fragment_open_exit" />
And this is my bottomNavigationMenu's XML:
<item
android:id="#+id/settingsFragment"
android:icon="#drawable/ic_settings"
android:title="Settings" />
Remember that the ID in the Navigation & Menu should be the same. As you see in the codes, the ID of "Settings Fragment" is the same:
android:id="#+id/settingsFragment"
I don't know if you know how to add preferences.xml in your resources. Just for sure I write it too:
Right Click on "res" New > Android Resource Directory
In the Resource Type field, pickup XML. Now you gonna have xml folder under "res". Again:
Right Click on "xml" New > XML Recourse File
Now, Here is my "preferences.xml":
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Weather Location">
<SwitchPreference
android:defaultValue="true"
android:disableDependentsState="true"
android:key="USE_DEVICE_LOCATION"
android:summary="Allow The App To Get Your Location"
android:title="Use Device Location" />
<EditTextPreference
android:defaultValue="Tehran"
android:dependency="USE_DEVICE_LOCATION"
android:key="CUSTOM_LOCATION"
android:summary="The Location For Which The Weather Is Displayed"
android:title="Location" />
</PreferenceCategory>
<PreferenceCategory android:title="Units">
<ListPreference
android:defaultValue="METRIC"
android:entries="#array/unitSystemEntries"
android:key="UNIT_SYSTEM"
android:summary="%s"
android:title="Unit System"
android:entryValues="#array/unitSystemValues"/>
</PreferenceCategory>
</PreferenceScreen>
Then create a "Kotlin" or "Java" class and set the XML to your class like this (depend on which language are you writing):
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.preferences)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(activity as? AppCompatActivity)?.supportActionBar?.title = "Settings"
(activity as? AppCompatActivity)?.supportActionBar?.subtitle = null
}
}
And here is my Application Class:
class ForecastApplication : Application(){
override fun onCreate() {
super.onCreate()
PreferenceManager.setDefaultValues(this, R.xml.preferences, false)
}
}
and in your application's Manifest, inside the application tag, define the Application class you already created.
android:name=".ForecastApplication"
I hope this is what you needed.
I have created Navigation Drawer Activity using Android Studio project template and added few menu items programatically and set the item selected listener to navigate to destination fragment.
Here what I am trying to do is clicking on each menu item added above should open the same destination fragment say HomeFragment but with different arguments so that I can reuse the layout.
So far it is working great with only one problem that the menu items are not highlighting correctly and Home item is always checked. I think this is because I have added the self link to home fragment. Is there any way to fix this?
MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navController = Navigation.findNavController(this, R.id.nav_host_fragment);
// Adding menu items
Menu menu = navigationView.getMenu();
SubMenu labels = menu.addSubMenu("Labels");
labels.add(R.id.group_labels, 201, 201, "Label 1").setIcon(R.drawable.ic_menu_gallery);
labels.add(R.id.group_labels, 202, 202, "Label 2").setIcon(R.drawable.ic_menu_gallery);
navigationView.invalidate();
appBarConfig = new AppBarConfiguration.Builder(R.id.home)
.setDrawerLayout(drawer)
.build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfig);
NavigationUI.setupWithNavController(navigationView, navController);
// Navigation item click listener
navigationView.setNavigationItemSelectedListener(item -> {
if (item.getGroupId() == R.id.group_labels) {
HomeFragmentDirections.ActionHomeSelf action = HomeFragmentDirections.actionHomeSelf();
action.setLabel(item.getTitle().toString());
navController.navigate(action);
}
navigationView.setCheckedItem(item.getItemId()); // Not working
NavigationUI.onNavDestinationSelected(item, navController);
drawer.closeDrawer(GravityCompat.START);
return true;
});
}
mobile_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/home">
<fragment
android:id="#+id/home"
android:label="#string/menu_home"
android:name=".fragments.HomeFragment"
tools:layout="#layout/fragment_home">
<argument
android:name="label"
app:argType="string"
android:defaultValue="default label" />
<action
android:id="#+id/action_home_self"
app:destination="#id/home"
app:launchSingleTop="false">
</action>
<action
android:id="#+id/action_home_to_blank"
app:destination="#id/blankFragment" />
</fragment>
<fragment
android:id="#+id/blankFragment"
android:name=".BlankFragment"
android:label="fragment_blank"
tools:layout="#layout/fragment_blank" />
</navigation>
activity_main_drawer.xml
<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/home"
android:icon="#drawable/ic_menu_camera"
android:orderInCategory="0"
android:title="#string/menu_home" />
<item
android:id="#+id/blankFragment"
android:icon="#drawable/ic_menu_camera"
android:orderInCategory="0"
android:title="#string/hello_blank_fragment" />
</group>
<item
android:orderInCategory="200"
android:title="#string/drawer_menu_group_labels">
<menu>
<group
android:id="#+id/group_labels"
android:checkableBehavior="single" />
</menu>
</item>
<item
android:orderInCategory="300"
android:title="#string/drawer_menu_group_pages">
<menu>
<group
android:id="#+id/group_pages"
android:checkableBehavior="single" />
</menu>
</item>
</menu>
I am trying to make logout button in the navigation section in Navigation Drawer Activity. In this case I do not need to open fragment. When the button is clicked Login page needs to be show up. But when I click the button it doesn't do anything. Do I need a fragment? like start activity in the fragment?
if fragment is mandatory is there anyway app goes back to main fragment when I push "back" button on the phone? MainFragment (first fragment -> logout fragment -> signin activity and when I click "back" button can I make it goes to first fragment instead going to logout (2nd) fragment.
So this is how I coded but did not work.
Under menu folder activity_drawer
<?xml version="1.0" encoding="utf-8"?>
<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/nav_menu"
android:icon="#drawable/ic_restaurant_black_24dp"
android:title="#string/menu_Menu" />
<item
android:id="#+id/nav_cart"
android:icon="#drawable/ic_shopping_cart_black_24dp"
android:title="#string/menu_cart" />
<item
android:id="#+id/nav_orders"
android:icon="#drawable/ic_assignment_turned_in_black_24dp"
android:title="#string/menu_orders" />
<item
android:id="#+id/nav_logout"
android:icon="#drawable/ic_exit_to_app_black_24dp"
android:title="#string/menu_Logout" />
</group>
</menu>
Since I do not need to use fragment I did not define it in mobile_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/nav_menu">
<fragment
android:id="#+id/nav_menu"
android:name="com.dav2020.orderforme.ui.menu.MenuFragment"
android:label="#string/menu_Menu"
tools:layout="#layout/fragment_memu">
</fragment>
<fragment
android:id="#+id/nav_cart"
android:name="com.dav2020.orderforme.ui.cart.CartFragment"
android:label="#string/menu_cart"
tools:layout="#layout/fragment_cart" />
<fragment
android:id="#+id/nav_orders"
android:name="com.dav2020.orderforme.ui.orders.OrdersFragment"
android:label="#string/menu_orders"
tools:layout="#layout/fragment_orders" />
</navigation>
And this is the code
DrawerLayout drawer = findViewById(R.id.drawer_layout);
final NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_menu, R.id.nav_cart, R.id.nav_orders, R.id.nav_logout)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
#Override
public void onDestinationChanged(#NonNull NavController controller, #NonNull NavDestination destination, #Nullable Bundle arguments) {
int menuId = destination.getId();
switch (menuId){
case R.id.nav_menu:
fab.show();
break;
case R.id.nav_cart:
//Intent cartIntent = new Intent (Home.this, Cart.class);
//startActivity(cartIntent);
fab.hide();
break;
case R.id.nav_orders:
//Intent orderIntent = new Intent (Home.this, OrderStatus.class);
//startActivity(orderIntent);
fab.hide();
break;
case R.id.nav_logout:
Intent signIn = new Intent(Home.this, SignInActivity.class);
signIn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(signIn);
fab.hide();
break;
default:
fab.show();
}
}
});
I have DrawerLayout and NavigationView. There are two fragments which are changed when I click on item in navigation drawer and that works well:
<fragment
android:id="#+id/nav_settings"
android:label="#string/menu_settings"
tools:layout="#layout/fragment_settings" />
<fragment
android:id="#+id/nav_themes"
android:label="#string/menu_themes"
tools:layout="#layout/fragment_themes" />
The problem is that I have several other items in the drawer menu that are not Fragments and I can not make them clickable:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group
android:id="#+id/group_1"
android:checkableBehavior="single">
<item
android:id="#+id/nav_settings"
android:icon="#drawable/ic_keyboard_settings"
android:title="#string/menu_settings" />
<item
android:id="#+id/nav_themes"
android:icon="#drawable/ic_theme"
android:title="#string/menu_themes" />
</group>
<group android:id="#+id/group_2">
<item
android:id="#+id/nav_developer_page"
android:icon="#drawable/ic_developer_page"
android:title="#string/menu_developer_page" />
<item
android:id="#+id/nav_privacy_policy"
android:icon="#drawable/ic_privacy_policy"
android:title="#string/menu_privacy_policy" />
</group>
</menu>
Here is the code:
setSupportActionBar(toolbar)
toggle = object : ActionBarDrawerToggle(this, drawer_layout, toolbar, 0, 0) {
override fun onDrawerClosed(drawerView: View) {
super.onDrawerClosed(drawerView)
syncState()
}
override fun onDrawerOpened(drawerView: View) {
super.onDrawerOpened(drawerView)
syncState()
}
}
toggle.syncState()
drawer_layout.addDrawerListener(toggle)
val navController = findNavController(R.id.nav_host_fragment)
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_settings, R.id.nav_themes, R.id.nav_developer_page), drawer_layout)
nav_view.setupWithNavController(navController)
toggle.syncState()
When I set NavigationItemSelectedListener it breaks navigation for Fragments.
How can I make those two items clickable and call a function?
The solution is to get the menu item from the navigation view and set a click listener:
val signoutMenuItem = binding.nvNavigationDrawerNavigationView.menu.findItem(id.navigation_drawer_menu_sign_out)
signoutMenuItem.setOnMenuItemClickListener {
navigationDrawerMainActivityViewModel.signOut()
true
}
and do not include non-fragment items in AppBarConfiguration:
appBarConfiguration = AppBarConfiguration(
setOf(
id.drawerFragmentX,
id.drawerFragmentY,
//id.navigation_drawer_menu_sign_out <- Do NOT include
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
This solution is identical to https://stackoverflow.com/a/59451345/5189200.
Xavi