Remove item at given position in Navigation Drawer - android

My users can delete items in my Navigation Drawer, they select which one they wish to delete and it should be removed from the menu.
Here is how I try to do it so far:
// Should remove item at position 'which'
private void removeTab(int which) {
NavigationView navView = (NavigationView) findViewById(R.id.nav_view);
Menu menu = navView.getMenu();
menu.removeItem(which + 1);
}
But it does not remove the item.
I'm not sure this is how removeItem should work, is there a way to remove an item in a Navigation Drawer using its position in the menu?
EDIT:
I get the idea of hiding the item, but that is problematic as I will have to keep track of the number of items hidden in order to hide the next one. (If Item1 and Item2 are hidden then Item3 is still at position 3 and not 1 when displayed).

NavigationView navigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hideItem();
}
private void hideItem()
{
navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu nav_Menu = navigationView.getMenu();
nav_Menu.findItem(R.id.nav_settings).setVisible(false);
}

You can hold the data in an arraylist. When you swipe over an item, you can remove the item from the array list arraylist.remove(index) and call adapter.notifyDataSetChanged().
Important:
If you implement this solution, you have to pass the arraylist to the adapter and work on the same list object.

you need to provide the id of MenuItem to be removed inside removeItem. not position.
like this:
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
navigationView.getMenu().removeItem(item.getItemId());
}
});

Related

Android: Handling a switch in drawer menu

I have only one user setting in my app, and I want to put it into the navigation drawer with a switch added to the given menu item.
Here is the relevant menu code:
<item
android:id="#+id/nav_dark"
android:checkable="true"
android:icon="#drawable/round_brightness_4_24"
android:title="#string/menu_dark"
app:actionViewClass="android.widget.Switch" />
The switch does appear on the right side of the menu item.
My listener:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.nav_dark) {
// code to apply dark or light theme
// works as expected
}
else {
// code to handle regular menu items
// it works too
}
return true;
}
My problems:
When I tap on R.id.nav_dark the item gets selected. I would like the colored overlay to stay on (or jump back to) the previous menu item, whose fragment is actually shown behind the drawer.
The switch does not react accordingly, even if I use item.setChecked(true) manually. I would like the switch to be turned on when the dark theme is enabled and turned off when it's disabled.
Tapping on the switch itself does not pass the event to the menu item. I would like them to work in sync.
I have seen checkboxes and swiches working like this in other applications, although, most of them were in the app bar's overflow menu. (I have tried mine with a checkbox too, but no difference.)
I solved this problem using this thread: Switch in Navigation drawer item with Design Support Library on Android
In this example the dedicated menu item switches between a light and dark theme, but you can use it to toggle any settings, of course.
Problems to solve
Implement our own onNavigationItemSelected listener, because the default solution created by Android Studio prevents the use of a dedicated menu item.
Implement the fragment transaction and toolbar handling logic.
Implement the onCheckedChange listener of the switch.
What we do is capture clicks on the menu items. If it's a regular item, we change the fragment behind the drawer. If it's the dedicated item with the switch, we manually toggle the switch, which calls its listener.
The actual code (changing the theme in this case) is handled by the listener of the switch. If you click on the switch itself, the listener will be called directly.
Relevant code from activity_main_drawer.xml menu file
<item
android:id="#+id/nav_dark"
android:checkable="true"
android:icon="#drawable/round_brightness_4_24"
android:title="#string/menu_dark"
app:actionViewClass="android.widget.Switch" /> <!-- you can also use a CheckBox -->
Relevant code from MainActivity.java
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, Switch.OnCheckedChangeListener {
private Toolbar toolbar;
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle toggle;
private NavigationView navigationView;
private Switch switchDark;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(getResources().getString(R.string.toolbar_title));
setSupportActionBar(toolbar);
// We have to handle the fragment changes manually,
// because what we do conflicts with the default solution created by Android Studio
drawerLayout = findViewById(R.id.drawer_layout);
toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.setDrawerIndicatorEnabled(true);
toggle.syncState();
navigationView = findViewById(R.id.nav_view);
// Check the menu item connected to the default fragment manually
navigationView.getMenu().findItem(R.id.nav_item1).setChecked(true);
navigationView.setNavigationItemSelectedListener(this); // See below!
switchDark = (Switch)navigationView.getMenu().findItem(R.id.nav_dark).getActionView();
// Set the default state of the switch connected to the menu item
switchDark.setChecked(AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES);
switchDark.setOnCheckedChangeListener(this); // See below!
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
// Handle the menu item with the switch
if (item.getItemId() == R.id.nav_dark) {
((Switch)item.getActionView()).toggle(); // Call the onCheckedChangeListener of the switch and let it do the work
return false; // Prevent the menu item to get selected (No overlay indicator will appear)
}
// Handle the other menu items
// We have to do this, because we deleted the default solution created by Android Studio
Fragment newFragment = null;
if (item.getItemId() == R.id.nav_item1) {
newFragment = new CustomFragment();
toolbar.setTitle(getResources().getString(R.string.custom_fragment_title));
}
else if (item.getItemId() == R.id.nav_item2) {
newFragment = new OtherFragment();
toolbar.setTitle(getResources().getString(R.string.other_fragment_title));
}
// Start the fragment transition manually
if (newFragment != null) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.nav_host_fragment, newFragment);
transaction.addToBackStack(null);
transaction.commit();
drawerLayout.close();
}
return true; // The selected item will have the overlay indicator
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(buttonView.getContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
int themeID;
if (isChecked) {
themeID = AppCompatDelegate.MODE_NIGHT_YES;
}
else {
themeID = AppCompatDelegate.MODE_NIGHT_NO;
}
AppCompatDelegate.setDefaultNightMode(themeID); // Change the theme at runtime
editor.putInt("themeID", themeID); // Save it to be remembered at next launch
editor.apply();
}
}
try this one.
<item
app:actionViewClass="androidx.appcompat.widget.SwitchCompat"
android:icon="#drawable/message"
android:title="All inboxes"
android:id="#+id/inbox"
/>
this above is the menu item we need
in order to get click events follow below steps mentioned
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
if (item.getItemId()==R.id.inbox){
((SwitchCompat) item.getActionView()).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked){
Toast.makeText(buttonView.getContext(), "Checked", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(buttonView.getContext(), "unChecked", Toast.LENGTH_SHORT).show();
}
}
});
}
Toast.makeText(MainActivity.this, ""+item.getTitle(), Toast.LENGTH_SHORT).show();
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
});
we already given our action class in menu item from xml .
we just need to verify which item it was and when it happens we can get the actionviewclass that we had assigned
and an onclicklistener on it .. this one worked for me .

How to change the items of a navigation drawer after login

i am developping an android app that contain a navigation drawer in which i have 4 items : Home , Connection , Contact , About us
When i click on Connection it opens a login fragment in which contains button to login
After clicking on login i wanna change the visibity on connection item to false and logout to true
Please help me
You should make following changes after the login is done......
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
//all other stuff of app here
...
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
// for getting menu from navigationView
Menu menu = navigationView.getMenu();
// finding menuItem that you want to change
MenuItem nav_connection = menu.findItem(R.id.nav_connection);
// set new title to the MenuItem"change name from connection to logout"
nav_connection.setTitle("Logout");
// add NavigationItemSelectedListener to check the navigation clicks
navigationView.setNavigationItemSelectedListener(this);
}
Hope this will help you,
works fine for me
You can achieve this feature by implementing following logic. Initialize the following declaration :
private NavigationView navigationView;
private boolean isAfterLogin;
Initialize the navigationView
navigationView = (NavigationView) findViewById(R.id.nav_view);
Let us assume, after your successful login, you control goes back to activity having Navigation view. Implement a shared pref or some boolean variable to check if the activity is opened after successful login.
#Override
protected void onResume() {
super.onResume();
isAfterLogin = checkForLogin(); // create this method to check your login status to avoid compilation error.
if(isAfterLogin){
Menu navigationMenu = navigationView.getMenu();
navigationMenu.findItem(R.id.nav_connection).setVisible(false);
navigationMenu.findItem(R.id.nav_logout).setVisible(true);
}
The value R.id.nav_connection is the id defined in navigation drawer menu.
Hope it solves the problem. Revert if you face any issue.

How to disable navigation drawer menu button?

What i want here when i move to another Fragment by clicking in NavigationDrawer menu button then button should be disabled.
Because addToBackStack(); method add multiple times in their stack when click again and again. So wanted to disable it when i move to another fragment.
To disable toggle button in navigation drawer use
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
to enable use LOCK_MODE_LOCKED_OPEN replacing LOCK_MODE_LOCKED_CLOSED
To disable drawer item click
Refer Hide Some Navigation Drawer Menu Item - Android there you can hide it
If you do not wish to hide in onNavigationItemSelected where you check (id == R.id.whatevertheitemid) also use a Boolean to allow access as you wish
eg
if (id == R.id.whatevertheitemid && isAccessGiven) { // do your task
}
Its helps me to solve this issue:
#Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
if(id==R.id.nav_item1){ //use can write your menu item here
return false;
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Use this to disable menu item:
NavigationView navigationView;
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
Now in menu item click:
Menu menuView= navigationView.getMenu();
menuView.getItem(ID).setEnabled(false);
in kotlin:
navigation.menu.findItem(R.id.your_target_item_id).setEnabled(false)
this is work for me and disabled item in drawerToggle menu
in Java:
NavigationView navigation = (NavigationView) findViewById(R.id.navigation);
navigation.getMenu().getMenu().findItem(R.id.your_target_item_id).setEnabled(false);

How to change Navigation Item Selected programmatically

When I created a new project I used Navigation Drawer Activity
app screen
Now each menu item when I click on it will open a fragment by calling a method name replacement.
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_home) {
replaceFragment(0);
setTit = "Your State Info.";
setTitle(setTit);
} else if (id == R.id.nav_flashcards) {
replaceFragment(1);
setTit = "Flash Cards";
setTitle(setTit);
in fragment 1 I have a RadioGroup when the checked change will open the fragmet depends on the radio checked.
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
RadioButton radioButton = (RadioButton)getActivity().findViewById(i);
if(radioButton.getTag()==1)
((MainActivity) getActivity()).replaceFragment(0);
else if ((radioButton.getTag()==2))
((MainActivity) getActivity()).replaceFragment(2);
}
The App work fine , but the issue is how can I change the Navigation Item Selected and also change the title for the action bar.
it's possible to use this way
((MainActivity) getActivity()).onNavigationItemSelected(menuitem);
but from the fragment how can I access the the items in the menu>activity_main_drawer.xml and pass it through menuitem
This works for me..
NavigationView navigationView = (NavigationView) getActivity().findViewById(R.id.nav_view);
navigationView.getMenu().getItem(2).setChecked(true);
In your fragment you have to add setOptionsMenu(true)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Add your menu entries here
super.onCreateOptionsMenu(menu, inflater);
}
question is not clear.
whole point of navigation drawer with fragments is to access navigation and its main toolbar all over the fragments with a single main activity.(the blue color one in your image, you should be able to change this anytime when you load a fragment)
But you need to make the frame/parent view of the fragments blow the tool bar view(that's why normally it comes with two XMLs, activtyMain.xml and contentMain.xml where content main is included below the tool bar in activityMain.XML) so you create fragments view match_parent to this contentMain.xml ,you can see toolbar is accessible to the each and every fragment you add in that view because its in the main activity where fragment/s add.
so you have a main activity and inside that you have fragment/s frame. Doesn't matter what fragment you load you can still have the access to main toolbar.
so once you check which item got clicked in navigationDrawer you load the fragment related to that right?. and there access the main toolbar of the mainActivity and do the changes that you need to display.That's it!
if (id == R.id.nav_whatever) {
// access toolBar or any view in main activity and do the changes
// call relevant fragment
}
But you cannot access that toolbar or mainActivity views inside your Fragment class that you try to attempt.
Edit :
Keep a Boolean in a Constant class or something similar,
then when you click on your button on second fragment change the value .
Now let's say Boolean is true
Then you click the navigation drawer again
// keep the id as it is and use the Boolean to check where you needs to go
if (id == R.id.nav_whatever) {
if(boolianName){
// boolianName is true go load second fragment
}else{
// load firstfragment
}
}
If you use Navegation drawer, you can use this code, put it on onCreate method:
NavigationView navigationView = (NavigationView) getActivity().findViewById(R.id.nav_view);
navigationView.getMenu().getItem(2).setChecked(true);

How to programatically disable and enable items every time an Android NavigationView is displayed

I am moving some menu items from the options menu to the navigation menu. My app uses a NavigationView that is populated by a menu as described at https://developer.android.com/reference/android/support/design/widget/NavigationView.html
One of the items calls webView.goBack() on the WebView in the main activity. When it was placed in the options menu, it was only enabled if webView.canGoBack(). Otherwise, it was disabled (grayed out). To accomplish this, onPrepareOptionsMenu() included the command:
back.setEnabled(webView.canGoBack());
As onPrepareOptionsMenu() is called every time the options menu is about to be displayed, this would update the status of the menu item to correctly reflect the state of the WebView.
However, I have not been able to replicate this behavior with the NavigationView. Is there a method or class similar to onPrepareOptionsMenu() that is called each time the NavigationView is prepared?
PS. Other people who have addressed similar questions have always referred to using a ListView, which was an older method of populating a navigation drawer. This question specifically relates to using a NavigationView with a menu.
The answer to this question is to add a DrawerListener and override onDrawerStateChanged.
// Create the navigation drawer.
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
// The `DrawerTitle` identifies the drawer in accessibility mode.
drawerLayout.setDrawerTitle(GravityCompat.START, getString(R.string.navigation_drawer));
// Listen for touches on the navigation menu.
final NavigationView navigationView = (NavigationView) findViewById(R.id.navigationView);
navigationView.setNavigationItemSelectedListener(this);
// Get handles for `navigationMenu` and the back and forward menu items. The menu is zero-based, so item 1 and 2 and the second and third items in the menu.
final Menu navigationMenu = navigationView.getMenu();
final MenuItem navigationBackMenuItem = navigationMenu.getItem(1);
final MenuItem navigationForwardMenuItem = navigationMenu.getItem(2);
// The `DrawerListener` allows us to update the Navigation Menu.
drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
}
#Override
public void onDrawerOpened(View drawerView) {
}
#Override
public void onDrawerClosed(View drawerView) {
}
#Override
public void onDrawerStateChanged(int newState) {
// Update the back and forward menu items every time the drawer opens.
navigationBackMenuItem.setEnabled(webView.canGoBack());
navigationForwardMenuItem.setEnabled(webView.canGoForward());
}
});
NavigationView exposes its underlying Menu with getMenu(). You can use that to find menu items and make changes to them.

Categories

Resources