简体   繁体   中英

How to add toggle button in menu item in android

I have options menu item in my application. Requirement was to add a toggle button to a menu item. Is this possible?

As of this writing there are 3 options .

1) Use app:actionViewClass . Example:

<?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="Switch!"
        app:actionViewClass="android.widget.Switch"
        app:showAsAction="always" />
</menu>

2) You can use a custom layout in a menu item to add toggle button. Example:

Create a layout with Switch (alternatively, you may also use ToggleButton ), res/layout/menu_switch.xml :

<?xml version="1.0" encoding="utf-8"?>
<Switch xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:padding="64dp" />

And use that layout in menu item:

<?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/switch_button_title"
        app:actionLayout="@layout/menu_switch"
        app:showAsAction="always" />
</menu>

3) You need to set android:checkable property of the menu to true and control its checked state in runtime. Example:

Menu :

<item
    android:id="@+id/checkable_menu"
    android:checkable="true"
    android:title="@string/checkable" />

Activity :

private boolean isChecked = false;

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    MenuItem checkable = menu.findItem(R.id.checkable_menu);
    checkable.setChecked(isChecked);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.checkable_menu:
            isChecked = !item.isChecked();
            item.setChecked(isChecked);
            return true;
        default:
            return false;
    }
}

Hope this helps.

I had a couple of issues when using a actionViewClass="android.widget.Switch in a menu item. It does actually show a switch on the ToolBar , although for me:

  • The onOptionsItemSelected() doesn't actually get called when I toggle the switch.
  • Using setChecked() on the MenuItem doesn't toggle its state.

Upon debugging and removing the actionViewClass="android.widget.Switch , the onOptionsItemSelected() gets called again.

Not sure what was going on; Maybe that I am using a custom ActionBar that I set using setSupportActionBar() , and using OptionsMenu callbacks within a fragment by enabling it with setHasOptionsMenu(true) .

I get this solved by inflating the switch itself, and set OnCheckedChangeListener on it

<item
    android:id="@+id/my_switch"
    android:title=""
    app:actionViewClass="androidx.appcompat.widget.SwitchCompat"
    app:showAsAction="always" />

And in Fragment

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
    inflater.inflate(R.menu.my_menu, menu);
    MenuItem menuItem = menu.findItem(R.id.my_switch);
    SwitchCompat mySwitch = (SwitchCompat) menuItem.getActionView();

    mySwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
        // Do something when `isChecked` is true or false
    });

}

And to toggle the switch programmatically, call setChecked() on the Switch , not on the MenuItem .

use app:actionViewClass

 <item android:id="@+id/id"
    android:title="@string/string"
    app:actionViewClass="android.widget.ToggleButton"
    android:orderInCategory="80"
    app:showAsAction="always" />
public boolean onPrepareOptionsMenu(final Menu menu) {       
      if(super.mMapView.isTraffic()) 
           menu.findItem(MENU_TRAFFIC_ID).setIcon(R.drawable.traffic_off_48); 
      else 
           menu.findItem(MENU_TRAFFIC_ID).setIcon(R.drawable.traffic_on_48); 

      return super.onPrepareOptionsMenu(menu); 
 }

Do you mean you want to add a toggle button as one of the elements/items appearing in the options menu or add a button to a list item from the menu?

Then you can do it with a custom layout(use a ListView within if you want) and inflating it in the

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    return true;
}

and you can save the values each time the button is toggles.

public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {
    case R.id.btnToggleValue:
      // save it here
      return true;
    case R.id.btnSecond:
      ...
      return true;
    default:
      return super.onOptionsItemSelected(item);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM