How to add a switch to android action bar?
Solution 1:
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:
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:
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:
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:
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);