How to add a switch to android action bar?

AndroidAndroid Layout

Android Problem Overview


I would like to add a button switch similar to jellybean native look. (Blue/gray switch at the top of the view) enter image description here

Documentation shows how to create a menu there or add icons, but it does not say, how to add a custom elements. eg. a switch. http://developer.android.com/guide/topics/ui/actionbar.html

Android Solutions


Solution 1 - Android

Create a layout for the switch switch_layout.xml. Custom layouts for menu should always be RelativeLayout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <Switch
        android:id="@+id/switchForActionBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="" />

</RelativeLayout>

Then, in your mainmenu.xml add the item as follows

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/myswitch"
        android:title=""
        android:showAsAction="always"
        android:actionLayout="@layout/switch_layout"
    />   
</menu>

And in your activity, inflate the mainmenu.xml as you always do

getMenuInflater().inflate(R.menu.mainmenu, menu);
return true;

Solution 2 - Android

Finally figured out my problem: for those that's using the new AppCompat, you should be using android.support.v7.widget.SwitchCompat instead of Switch on the switch layout...otherwise, it won't show on the ActionBar (assumed you're using AppCompat ActionBar as well), well, the actionLayout attribute doesn't work, it has to be set in the code.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/switchView"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:orientation="horizontal">
	
	<android.support.v7.widget.SwitchCompat
		android:id="@+id/switchForActionBar"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:text="" />

</RelativeLayout>

Then set the layout in the code:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
	// Inflate the menu; this adds items to the action bar if it is present.
	getMenuInflater().inflate(R.menu.menu_main, menu);
	MenuItem item = menu.findItem(R.id.on_off_switch);
	item.setActionView(R.layout.on_off_switch);
	return true;
}

Solution 3 - Android

If the widget is not appearing in the action-bar it is probably because you are using appCompat for your action-bar. To solve this switch "android:" to "app:" in front of "showAsAction" and "actionLayout" in your menu.xml

Add item to xml, with app: in place of android:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
            <item
                android:id="@+id/myswitch"
                android:title=""
                app:showAsAction="always"
                app:actionLayout="@layout/switch_layout"
            />   
        </menu>

Make layout that you are using for your "app:actionLayout"
switch_layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    <Switch
        android:id="@+id/switchAB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        />
</RelativeLayout>

Inflate the menu in your ActionBarActivity as you would normally

   getMenuInflater().inflate(R.menu.mainmenu, menu);
    return true;

This should make the switch appear in your action-bar, if it was not appearing.

Solution 4 - Android

For those who want to add,

Checked change Listener to the same Switch

Kotlin

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.menu_main, menu)
    val item = menu!!.findItem(R.id.my_switch_item)
    item.setActionView(R.layout.switch_layout)

    val mySwitch = item.actionView.findViewById(R.id.switch_id)
    mySwitch.setOnCheckedChangeListener(object : CompoundButton.OnCheckedChangeListener{
        override fun onCheckedChanged(p0: CompoundButton?, isChecked: Boolean) {
            // do what you want with isChecked
        }
    })

    return true
}

Java

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    MenuItem item = menu.findItem(R.id.my_switch_item);
    item.setActionView(R.layout.switch_layout);

    Switch mySwitch = item.getActionView().findViewById(R.id.switch_id);
    mySwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
         @Override
         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                  // do something based on isChecked
         }
    });
    return true;
}

> P.S. You can change reference to Switch or SwitchCompat

Solution 5 - Android

The solution given by Ezequiel is awesome and works. Here goes another approach:

Define your custom layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" >
    <Switch
        android:id="@+id/actionbar_switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="" />
</RelativeLayout>

Inflate it programatically:

ActionBar actionBar = getSupportActionBar();
actionBar.setCustomView(R.layout.actionbar_top);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_CUSTOM);
...
Switch button = (Switch) findViewById(R.id.actionbar_switch);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArturs VancansView Question on Stackoverflow
Solution 1 - AndroidEzequielView Answer on Stackoverflow
Solution 2 - AndroidVu NguyenView Answer on Stackoverflow
Solution 3 - AndroidNeil M.View Answer on Stackoverflow
Solution 4 - AndroidgprathourView Answer on Stackoverflow
Solution 5 - AndroidRudolf RealView Answer on Stackoverflow