¿how to fix side menu functionality in android studio? - android

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.

Related

onNavigationItemSelected is not working on Navigation Drawer

I'm trying to get click event of Navigation Drawer item.
What I did is as below.
(1) Create a new Android source project selecting 'Navigation Drawer Activity' on 'Select a Project Template'. (Min SDK : API 22 - Lollipop)
(2) Add one item on '/res/menu/activity_main_drawer.xml'.
<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>
<item
android:id="#+id/menu_notification"
android:icon="#drawable/ic_menu_slideshow"
android:title="Notification" />
(3) MainActivity implements NavigationItemSelectedListener, and define event function - onNavigationItemSelected()
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_notification) {
Toast.makeText(this, "Menu - Notification", Toast.LENGTH_SHORT).show();
}
return true;
}
(4) Set NavigationItemSelectedListener to MainActivity in onCreate() method.
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);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.bringToFront();
navigationView.setNavigationItemSelectedListener(this);
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);
}
This is all I did. After run this application on Emulator, I clicked new menu item (Notification), but nothing happened.
onNavigationItemSelected() can not get event of item click.
What I have to do to get click event of Navigation Drawer item?
The reason why this doesn't work is because you are using Navigation Component. If you want onNavigationItemSelected method to be called, remove the mentioned line below:
NavigationUI.setupWithNavController(navigationView, navController);
After that, keep in mind that you should manage selected items manually as Navigation won't do it for you anymore.

Android: How do I get the Settings menu to appear with NavigationUI?

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.

How is Android Studio Navigation Drawer navigating different Fragments?

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".

Android jetpack component - toast on navigation drawer click

I am using navigation jetpack and have set up navigation drawer. Every thing works fine. But the problem is I want to show a toast when user clicks "nav_share" but it is not showing...
here is how i made navigation drawer
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_plan, R.id.navigation_notifications)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
my menu for navigation drawer 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"
tools:showIn="navigation_view">
<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" />
<item
android:id="#+id/nav_tools"
android:icon="#drawable/ic_menu_manage"
android:title="#string/menu_tools" />
</group>
<item android:title="Communicate">
<menu>
<item
android:id="#+id/nav_share"
android:icon="#drawable/ic_menu_share"
android:title="#string/menu_share" />
<item
android:id="#+id/nav_send"
android:icon="#drawable/ic_menu_send"
android:title="#string/menu_send" />
</menu>
</item>
</menu>
finally:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
int id = menuItem.getItemId();
if (id == R.id.nav_share)
Toast.makeText(LauncherActivity.this, "Click", Toast.LENGTH_SHORT).show();
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
i want that click toast...i cannot see what am i missing....
if any one wants the answer..i did some research and finally found a solution to it...hope it helps....
NavigationView navigationView = findViewById(R.id.nav_view);
MenuItem shareItem = navigationView.getMenu().findItem(R.id.nav_share);
shareItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(LauncherActivity.this, "click", Toast.LENGTH_SHORT).show();
//do as you want with the button click
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
});
Use this
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.bringToFront()
navigationView.setNavigationItemSelectedListener(this);
I also had your problem and came up with the solution
NavController navController = Navigation.findNavController(this, R.id.nav_host_home);
NavigationUI.setupWithNavController(navigationView, navController);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
int id = menuItem.getItemId();
if (id == R.id.nav_share) {
Toast.makeText(getApplicationContext(), "nav_share", Toast.LENGTH_SHORT).show();
}
NavigationUI.onNavDestinationSelected(menuItem, navController);
drawerLayout.closeDrawer(Gravity.RIGHT);
return true;
}
});
In case if anyone is still searching for the answer as to how we can tie up navigation destinations and also handle click on menu items of the navigation drawer, it has been answered here: https://stackoverflow.com/a/57846680/3283350
Android Jetpack Navigation - Custom Action with Drawer Item
Simple step and easy
class MainActivity : AppCompatActivity(),NavigationView.OnNavigationItemSelectedListener{
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val navView: NavigationView = binding.navView
navController = findNavController(R.id.nav_host_fragment_content_main)
navView.setNavigationItemSelectedListener(this)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
val url: String? = when (item.itemId) {
R.id.nav_privacy_policy -> MenuItemUrl.PRIVACY_POLICY
R.id.nav_term_condition -> MenuItemUrl.TERM_AND_CONDITION
R.id.nav_contact_us -> MenuItemUrl.CONTACT_US
R.id.nav_feedback -> MenuItemUrl.FEEDBACK
R.id.nav_help_support -> MenuItemUrl.HELP_AND_SUPPORT
R.id.nav_faq -> MenuItemUrl.FAQ
R.id.nav_about_us -> MenuItemUrl.ABOUT_US
else -> null
}
if (url != null) Methods.openBrowser(this#MainActivity, url) // Do anything here ex. show toast etc.
NavigationUI.onNavDestinationSelected(item, navController)
drawerLayout.closeDrawer(GravityCompat.START)
return true
}
}

Navigation drawer: How do I set the selected item at startup?

My code works perfectly: every time an item in Navigation Drawer is clicked the item is selected.
Of course I want to start the app with a default fragment (home), but Navigation Drawer doesn't have the item selected. How can I select that item programmatically?
public class BaseApp extends AppCompatActivity {
//Defining Variables
protected String LOGTAG = "LOGDEBUG";
protected Toolbar toolbar;
protected NavigationView navigationView;
protected DrawerLayout drawerLayout;
private DateManager db = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_layout);
navigationView = (NavigationView) findViewById(R.id.navigation_view);
// set the home/dashboard at startup
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, new DashboardFragment());
fragmentTransaction.commit();
setNavDrawer();
}
private void setNavDrawer(){
// Initializing Toolbar and setting it as the actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing NavigationView
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Checking if the item is in checked state or not, if not make it in checked state
// I THINK THAT I NEED EDIT HERE...
if (menuItem.isChecked()) menuItem.setChecked(false);
else menuItem.setChecked(true);
//Closing drawer on item click
drawerLayout.closeDrawers();
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()) {
//Replacing the main content with ContentFragment
case R.id.home:
DashboardFragment dashboardFragment = new DashboardFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, dashboardFragment,"DASHBOARD_FRAGMENT");
fragmentTransaction.commit();
return true;
[...]
I think that I need to edit here:
if (menuItem.isChecked()) menuItem.setChecked(false);
else menuItem.setChecked(true);
Or in onCreate at App startup with FragmentTransaction.
Thank you for your support.
Use the code below:
navigationView.getMenu().getItem(0).setChecked(true);
Call this method after you call setNavDrawer();
The getItem(int index) method gets the MenuItem then you can call the setChecked(true); on that MenuItem, all you are left to do is to find out which element index does the default have, and replace the 0 with that index.
You can select(highlight) the item by calling
onNavigationItemSelected(navigationView.getMenu().getItem(0));
Here is a reference link: http://thegeekyland.blogspot.com/2015/11/navigation-drawer-how-set-selected-item.html
EDIT
Did not work on nexus 4, support library revision 24.0.0. I recommend use
navigationView.setCheckedItem(R.id.nav_item);
answered by #kingston below.
You can also call:
navigationView.setCheckedItem(id);
This method was introduced in API 23.0.0
Example
<?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:ignore="UnusedIds">
<group
android:id="#+id/group"
android:checkableBehavior="single">
<item
android:id="#+id/menu_nav_home"
android:icon="#drawable/ic_home_black_24dp"
android:title="#string/menu_nav_home" />
</group>
</menu>
Note: android:checkableBehavior="single"
See also this
For me both these methods didn't work:
navigationView.getMenu().getItem(0).setChecked(true);
navigationView.setCheckedItem(id);
Try this one, it works for me.
onNavigationItemSelected(navigationView.getMenu().findItem(R.id.nav_profile));
Example (NavigationView.OnNavigationItemSelectedListener):
private void setFirstItemNavigationView() {
navigationView.setCheckedItem(R.id.custom_id);
navigationView.getMenu().performIdentifierAction(R.id.custom_id, 0);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setFirstItemNavigationView();
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
FragmentManager fragmentManager = getFragmentManager();
switch (item.getItemId()) {
case R.id.custom_id:
Fragment frag = new CustomFragment();
// update the main content by replacing fragments
fragmentManager.beginTransaction()
.replace(R.id.viewholder_container, frag)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.addToBackStack(null)
.commit();
break;
}
Tks
There are always problems with Googles "oh so great" support libs. If you want to check an item without downgrading your support libs version, just set checkable before setting checked state.
MenuItem item = drawer.getMenu().findItem(R.id.action_something);
item.setCheckable(true);
item.setChecked(true);
It might also work if you set checkable in the menu xml files
You can both highlight and select the item with the following 1-liner:
navigationView.getMenu().performIdentifierAction(R.id.posts, 0);
Source: https://stackoverflow.com/a/31044917/383761
API 23 provides the following method:
navigationView.setCheckedItem(R.id.nav_item_id);
However, for some reason this function did not cause the code behind the navigation item to run. The method certainly highlights the item in the navigation drawer, or 'checks' it, but it does not seem to call the OnNavigationItemSelectedListener resulting in a blank screen on start-up if your start-up screen depends on navigation drawer selections. It is possible to manually call the listener, but it seems hacky:
if (savedInstanceState == null) this.onNavigationItemSelected(navigationView.getMenu().getItem(0));
The above code assumes:
You have implemented
NavigationView.OnNavigationItemSelectedListener in your activity
You have already called:
navigationView.setNavigationItemSelectedListener(this);
The item you wish to select is located in position 0
You have to call 2 functions for this:
First: for excuting the commands you have implemented in onNavigationItemSelected listener:
onNavigationItemSelected(navigationView.getMenu().getItem(R.id.nav_camera));
Second: for changing the state of the navigation drawer menu item to selected (or checked):
navigationView.setCheckedItem(R.id.nav_camera);
I called both functions and it worked for me.
Following code will only make menu item selected:
navigationView.setCheckedItem(id);
To select and open the menu item, add following code after the above line.
onNavigationItemSelected(navigationView.getMenu().getItem(0));
Easiest way is to select it from xml as follows,
<menu>
<group android:checkableBehavior="single">
<item
android:checked="true"
android:id="#+id/nav_home"
android:icon="#drawable/nav_home"
android:title="#string/main_screen_title_home" />
Note the line android:checked="true"
This is my solution, very simple.
Here is my menu.xml file:
<group
android:id="#+id/grp1"
android:checkableBehavior="single">
<item
android:id="#+id/nav_all_deals"
android:checked="true"
android:icon="#drawable/ic_all_deals"
android:title="#string/all_deals" />
<item
android:id="#+id/nav_news_and_events"
android:icon="#drawable/ic_news"
android:title="#string/news_and_events" />
<item
android:id="#+id/nav_histories"
android:icon="#drawable/ic_histories"
android:title="#string/histories" />
</group>
Above menu will highlight the first menu item. Below line will do something(eg: show the first fragment, etc). NOTE: write after 'configure your drawer code'
onNavigationItemSelected(mNavigationView.getMenu().getItem(0));
on your activity(behind the drawer):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
navigationView.setCheckedItem(R.id.nav_portfolio);
onNavigationItemSelected(navigationView.getMenu().getItem(0));
}
and
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
if (id == R.id.nav_test1) {
fragment = new Test1Fragment();
displaySelectedFragment(fragment);
} else if (id == R.id.nav_test2) {
fragment = new Test2Fragment();
displaySelectedFragment(fragment);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
and in your menu:
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_test1"
android:title="#string/test1" />
<item
android:id="#+id/nav_test2"
android:title="#string/test2" />
</group>
so first menu is highlight and show as default menu.
First of all create colors for selected item. Here https://stackoverflow.com/a/30594875/1462969 good example. It helps you to change color of icon. For changing background of all selected item add in your values\style.xml file this
<item name="selectableItemBackground">#drawable/selectable_item_background</item>
Where selectable_item_background should be declared in drawable/selectable_item_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/accent_translucent"
android:state_pressed="true" />
<item android:drawable="#android:color/transparent" />
</selector>
Where color can be declared in style.xml
<color name="accent_translucent">#80FFEB3B</color>
And after this
// The main navigation menu with user-specific actions
mainNavigationMenu_ = (NavigationView) findViewById(R.id.main_drawer);
mainNavigationMenu_.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
mainNavigationMenu_.getMenu().findItem(itemId).setChecked(true);
return true;
}
});
As you see I used this
mainNavigationMenu_.getMenu().findItem(itemId).setChecked(true);
to set selected item.
Here navigationView
<android.support.design.widget.NavigationView
android:id="#+id/main_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/header_main_navigation_menu"
app:itemIconTint="#color/state_list"
app:itemTextColor="#color/primary"
app:menu="#menu/main_menu_drawer"/>
When using BottomNavigationView the other answers such as navigationView.getMenu().getItem(0).setChecked(true); and
navigationView.setCheckedItem(id); won't work calling setSelectedItemId works:
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation_view);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
// TODO: 10-Aug-19 your code here
}
});
bottomNavigationView.setSelectedItemId(R.id.myitem);
Below code is used to selected the first item and highlight the selected first item in the menu.
onNavigationItemSelected(mNavigationView.getMenu().getItem(0).setChecked(true));
you can do this,
nav_view.getMenu().findItem(R.id.menutem).setChecked(true)
package com.example.projectdesign;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.material.navigation.NavigationView;
public class MenuDrawer extends AppCompatActivity implements
NavigationView.OnNavigationItemSelectedListener{
public DrawerLayout drawerLayout;
public ActionBarDrawerToggle actionBarDrawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu_drawer);
drawerLayout = findViewById(R.id.my_drwaer_layout);
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
R.string.nav_open, R.string.nav_close);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
NavigationView navigationView = findViewById(R.id. nav_view ) ;
navigationView.setNavigationItemSelectedListener( this ) ;
}
#SuppressLint("ResourceType")
#SuppressWarnings ( "StatementWithEmptyBody" )
#Override
public boolean onNavigationItemSelected (MenuItem item){
int id=item.getItemId();
switch (id){
case R.id.nav_account:
Intent intent= new Intent(MenuDrawer.this, UsingBackKey.class);
startActivity(intent);
break;
case R.id.women:
getSupportFragmentManager().beginTransaction().replace(R.id.my_drwaer_layout,new
Fragment2()).commit();
break;
case R.id.men:
Toast.makeText(getApplicationContext(),"Soon",
Toast.LENGTH_SHORT).show();
break;
case R.id.kids:
Toast.makeText(getApplicationContext(),"Welcome to Kids",
Toast.LENGTH_SHORT).show();
break;
}
drawerLayout.closeDrawer(GravityCompat.START);
return super.onContextItemSelected(item);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
super.onBackPressed();
}
}
Make a selector for Individaual item of Nav Drawer
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/darkBlue" android:state_pressed="true"/>
<item android:drawable="#color/darkBlue" android:state_checked="true"/>
<item android:drawable="#color/textBlue" />
</selector>
Make a few changes in your NavigationView
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:itemBackground="#drawable/drawer_item"
android:background="#color/textBlue"
app:itemIconTint="#color/white"
app:itemTextColor="#color/white"
app:menu="#menu/activity_main_drawer"
/>
bottomNavigationView.setSelectedItemId(R.id.menuItem);
Above worked for me, but I had place it inside onResume() method. Placing inside
onNavigationItemSelected(#NonNull MenuItem item) caused me problems while switching back and forth between activities
private BottomNavigationView bottomNavigationView;
#Override
public void onResume(){
super.onResume();
bottomNavigationView.setSelectedItemId(R.id.menuItem);
}
For some reason it's preferable to find the MenuItem using the ID's.
drawer.getMenu().findItem(R.id.action_something).setChecked(true);

Categories

Resources