Switch in Navigation drawer item with Design Support Library on Android
O

9

13

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?

enter image description here

Ogham answered 13/6, 2015 at 21:43 Comment(2)
Hello @mlody, I wanted to ask. How do you add that switch in the Navigation Drawer. I have asked a question here = #33952401 - ThanksCanned
@Joolah Unfortunately I havent added this switch, because I didnt found way to do that without external NavigationDrawer.Ogham
H
27

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.

Homomorphism answered 6/10, 2016 at 18:2 Comment(10)
Thank you very much. It works. I regret that I did not know that a year ago.Ogham
How to add listener for switch, can you add codes to your respond plesaeJosefinejoseito
How do you add a listener to the switch since you apparently can't do it the normal way.Genna
mehmet & 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.Homomorphism
How to know if switch has toggled in java file ?Careaga
@Homomorphism if i use this in my menu, how listen for switch?Dinerman
roghayeh 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."Homomorphism
your code does not work. I kept getting Error inflating class com.google.android.material.navigation.NavigationViewBorderer
EdgeDev: there's something wrong with your code. Check your NavigationView stuff. Anyway, I don't recommend this approach, see my comment.Homomorphism
instead app:actionLayout use app:actionViewClass="com.google.android.material.switchmaterial.SwitchMaterial"Gladden
A
15

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.

Athenaathenaeum answered 4/4, 2016 at 22:36 Comment(1)
Disclaimer:Please confirm that you are using app:actionLayout="@layout/layout_menu_profile" and not android:actionLayout="@layout/layout_menu_profile"Perrins
P
14

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;
}
Ping answered 17/4, 2018 at 8:0 Comment(3)
If you get NULLPointer try this - switch is referenced inside nav item. (Switch) navigationView.getMenu().findItem(R.id.item).getActionView().findViewById(R.id.switch);Contentment
Disclaimer:Please confirm that you are using app:actionLayout="@layout/layout_menu_profile" and not android:actionLayout="@layout/layout_menu_profile"Perrins
@AbrahamMathew yes I am. You can see it in the answer itself.Ping
C
3

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();
        }

    });
Commonplace answered 20/9, 2017 at 18:2 Comment(0)
S
2

For those of you using Kotlin Extensions

  1. 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>
  1. 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" />
  1. Access in code
nav_view.menu.findItem(R.id.nav_notifications_switch)
    .actionView
    .toggleSwitch
    .setOnCheckedChangeListener { _, isChecked ->
        
    }
Samba answered 18/8, 2020 at 1:23 Comment(0)
N
1

simply yes you can do this easily, i will post my code so you can implement it

<item android:id="@+id/nav_item_1"
        android:title="Android"
        android:icon="@drawable/ic_android_black_24dp"
        android:checked="true"/>

and the Main Activity Layout should be :

<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<LinearLayout
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

    <TextView
        android:id="@+id/content_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="50dp"
        android:text="Your Content Goes Here"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@color/colorAccent" />

    <!-- your content layout -->

</LinearLayout>

<android.support.design.widget.NavigationView
    android:id="@+id/menu_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:menu="@menu/menu_drawer" />

And here's a step by step tutorial for Navigation Drawer using Design Library

Noelnoelani answered 4/8, 2015 at 22:55 Comment(1)
There is no Switch in your solution.Ogham
G
1

In res -> menu -> menu.xml create <item> with field: app:actionViewClass
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"
        xmlns:app="http://schemas.android.com/apk/res-auto">

        <item android:title="">
            <menu>
                <group android:checkableBehavior="single">

                    <item
                        android:checkable="false"
                        android:id="@+id/is_night_mode"
                        android:icon="@drawable/main_navigation_night_mode_light"
                        android:title="@string/main_navigation_night_mode"
                        app:actionViewClass="com.google.android.material.switchmaterial.SwitchMaterial" />
           
                </group>
            </menu>
        </item>
    </menu>

Next in Activity or Fragment find actionView like this:

val nightModeSwitch = binding.navView.menu.findItem(R.id.is_night_mode).actionView as SwitchMaterial

Set OnCheckedChangeListener

nightModeSwitch.setOnCheckedChangeListener { buttonView, isChecked ->
    //do something
}
Gladden answered 30/1, 2023 at 16:54 Comment(0)
S
0

You should be able to.

Your navigation drawer view can be a LinearLayout, and inside that, you can include your NavigationView and another ViewGroup adding the switches.

Sural answered 13/6, 2015 at 21:56 Comment(1)
Do 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.Ogham
N
0

If you have to update the switch in navigation with respect to it's toggling then it's better to use two different menu layouts with checked switch and without checked switch. So by checking the current state you can easily change the navigation drawer.

Nev answered 22/6, 2020 at 9:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.