Switch in Navigation drawer item with Design Support Library on Android
Solution 1
Your menu item for the navigation drawer:
<item
android:id="@+id/nav_item1"
android:icon="@drawable/ic_item1"
android:title="item1"
app:actionLayout="@layout/layout_switch"
/>
and the layout for that item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.SwitchCompat
android:id="@+id/drawer_switch"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:text=""/>
</LinearLayout>
EDIT:
I ended up using a different approach. In fact, I found out that you can use any view in the drawer, so there's no point in bothering with the menu stuff. Just create a view the usual way (with listeners, etc.) and add in to the drawer.
Solution 2
One way I have found of doing this would be to use setActionView on the menuItem you want:
mNavigationView.getMenu().findItem(R.id.nav_connect)
.setActionView(new Switch(this));
// To set whether switch is on/off use:
((Switch) mNavigationView.getMenu().findItem(R.id.nav_connect).getActionView()).setChecked(true);
Probably want a click listener as well to change the state of the Switch:
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.nav_connect:
((Switch) menuItem.getActionView()).toggle();
return true;
}
}
}
I haven't tried, but you could probably use android:actionLayout="@layout/switch_layout" in xml and point to a custom layout you created.
Also could try using an ActionProvider which might offer a little more robustness. I haven't tried this method either though.
Solution 3
None of the answers seems to be complete so after some more research here is what I came up with:
drawer_switch.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.SwitchCompat
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_switch"
android:layout_width="fill_parent"
android:layout_height="match_parent" />
drawer_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:title="@string/header">
<menu>
<item
android:id="@+id/switch_item"
android:icon="@drawable/ic_switch_item"
app:actionLayout="@layout/drawer_switch"
android:title="@string/switch_item" />
</menu>
</item>
</menu>
DrawerActivity.java:
SwitchCompat drawerSwitch = (SwitchCompat) navigationView.getMenu().findItem(R.id.switch_item).getActionView();
drawerSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
// do stuff
} else {
// do other stuff
}
}
});
DrawerActivity.java:
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.switch_item) {
return false;
}
closeDrawer();
return true;
}
Solution 4
I did something like this.
navigationView.getMenu().findItem(R.id.vibrate)
.setActionView(new Switch(this));
Switch vibrateSwitch =(Switch)
navigationView.getMenu().findItem(R.id.vibrate).getActionView();
vibrateSwitch.setChecked(true);
vibrateSwitch.setOnCheckedChangeListener(new
CompoundButton.OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean
isChecked){
SharedPreferences sharedPreferences =
getSharedPreferences(getString(R.string.MyPREFERENCES), MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(getString(R.string.VIBRATE), isChecked);
editor.commit();
}
});
Solution 5
For those of you using Kotlin Extensions
- Menu file
<menu 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">
<item
android:id="@+id/nav_notifications_switch"
android:icon="@drawable/ic_notifications"
android:title="@string/notifications"
app:actionLayout="@layout/drawer_notifications_switch" />
</menu>
- Switch layout file
<Switch xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toggleSwitch"
android:layout_width="fill_parent"
android:layout_height="match_parent" />
- Access in code
nav_view.menu.findItem(R.id.nav_notifications_switch)
.actionView
.toggleSwitch
.setOnCheckedChangeListener { _, isChecked ->
}
Marcin Lagowski
Java Developer. Interests: new technologies, functional programming, devops, docker, automation, continuous integration, android, kotlin.
Updated on June 14, 2022Comments
-
Marcin Lagowski almost 2 years
I need to put Switch inside item in navigation drawer. I'm using new design support library, but I cannot find if it is posibble at all. When using
android:checkable
item is just full selected and that is not what I wish.
This is screenshot of what I really want. Is that possible to achieve that?
-
Marcin Lagowski almost 9 yearsDo you mean to put <Switch> between <NavigationView> tags? I can do that but all I got is text view and switch drawn on navigation drawer ImageView not as part of it but on it.
-
Marcin Lagowski over 7 yearsThere is no Switch in your solution.
-
Marcin Lagowski over 7 yearsThank you very much. It works. I regret that I did not know that a year ago.
-
mehmet about 7 yearsHow to add listener for switch, can you add codes to your respond plesae
-
codemoonger almost 7 yearsHow do you add a listener to the switch since you apparently can't do it the normal way.
-
lenooh about 6 yearsmehmet & mogren3000: I ended up using a different approach. In fact, I found out that you can use any view in the drawer, so there's no point in bothering with the menu stuff. Just create a view the usual way (with listeners, etc.) and add in to the drawer.
-
gautam about 6 yearsHow to know if switch has toggled in java file ?
-
roghayeh hosseini over 5 years@lenooh if i use this in my menu, how listen for switch?
-
lenooh over 5 yearsroghayeh hosseini: As I wrote in my comment " I ended up using a different approach. In fact, I found out that you can use any view in the drawer, so there's no point in bothering with the menu stuff. Just create a view the usual way (with listeners, etc.) and add in to the drawer."
-
EdgeDev over 4 yearsyour code does not work. I kept getting
Error inflating class com.google.android.material.navigation.NavigationView
-
lenooh over 4 yearsEdgeDev: there's something wrong with your code. Check your
NavigationView
stuff. Anyway, I don't recommend this approach, see my comment. -
Pradeesh tet about 4 yearsIf you get NULLPointer try this - switch is referenced inside nav item. (Switch) navigationView.getMenu().findItem(R.id.item).getActionView().findViewById(R.id.switch);
-
Abraham Mathew almost 4 yearsDisclaimer:Please confirm that you are using app:actionLayout="@layout/layout_menu_profile" and not android:actionLayout="@layout/layout_menu_profile"
-
Abraham Mathew almost 4 yearsDisclaimer:Please confirm that you are using app:actionLayout="@layout/layout_menu_profile" and not android:actionLayout="@layout/layout_menu_profile"
-
Sir Codesalot almost 4 years@AbrahamMathew yes I am. You can see it in the answer itself.