10

I am trying to enable the user to stops and starts service which I am implementing from the Menu where the text is will be changed when he clicks it so I want to add ToggleButton as option in the menu tool but nothing is being display in my case now. How can I fix it?

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <ToggleButton
        android:id="@+id/toggle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textOff="Off"
        android:textOn="On" />
</menu>

MainActivity:

public class MainActivity extends ActionBarActivity {
    ToggleButton tButton;
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.toggle:

                tButton = (ToggleButton) findViewById(R.id.toggle);
                tButton.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        if (((ToggleButton) v).isChecked()) {
                            Intent i = new Intent(MainActivity.this,
                                                  TrackingService.class);
                            startService(i);
                            System.out.println("test is checked, start service");

                        } else {
                            // Stop the service when the Menu button clicks.
                            Intent i = new Intent(MainActivity.this,
                                                  TrackingService.class);
                            stopService(i);
                            System.out.println("test is NOT checked, stop service");

                        }

                    }
                });

                return true;

            default:
                return false;
        }
    }
}

Edit:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.checkable_menu:
        if (isChecked = !item.isChecked()) {
            item.setChecked(isChecked);

            Intent i = new Intent(this, TrackingService.class);
            startService(i);
            System.out.println("test if onOptionsItemSelected");
        } else {
            Intent i = new Intent(this, TrackingService.class);
            stopService(i);
            System.out.println("test else onOptionsItemSelected");

        }
        return true;

    default:
        System.out
                .println("test default onOptionsItemSelected was invoked.");
        return false;
    }
}
The Time
  • 697
  • 5
  • 12
  • 26

6 Answers6

15

It is easy. Rather you will have your toggle button on Toolbar.

<item
    android:id="@+id/show_secure"
    android:enabled="true"
    android:title=""
    android:visible="true"
    app:actionLayout="@layout/show_protected_switch"
    app:showAsAction="ifRoom" />

And this is your show_protected_switch.xml layout.

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

<ToggleButton
    android:id="@+id/switch_show_protected"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/switch_ptotected_btn_selector"
    android:textOff=""
    android:textOn=""/>
 </RelativeLayout>

And in code:

 ToggleButton mSwitchShowSecure;
 mSwitchShowSecure = (ToggleButton) menu.findItem(R.id.show_secure).getActionView().findViewById(R.id.switch_show_protected);
        mSwitchShowSecure.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if(b){
                    //Your code when checked

                } else {
                    //Your code when unchecked
                }Y
            }
        });

Output!

enter image description here

It is rather big but you can adjust its size, obviously

Faizan Mubasher
  • 4,427
  • 11
  • 45
  • 81
14

enter image description here

I know its very a long time to post an answer, but it may help someone :)

I followed this link and update some of the implemented solution as the app was crashed before these modifications

And below is the full solution: 1- Create a new xml file under layout folder and name it switch_layout.xml and put the below:

<?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>

2- Add the below menu item in the main.xml file under menu folder:

<item
    android:id="@+id/switchId"
    android:title=""
    app:actionLayout="@layout/switch_layout"
    app:showAsAction="always" />

3- Go to your activity and below is a full implementation for onCreateOptionsMenu method:

 @Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    MenuItem item = (MenuItem) menu.findItem(R.id.switchId);
    item.setActionView(R.layout.switch_layout);
    Switch switchAB = item
            .getActionView().findViewById(R.id.switchAB);
    switchAB.setChecked(false);

    switchAB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                                     boolean isChecked) {
            if (isChecked) {
                Toast.makeText(getApplication(), "ON", Toast.LENGTH_SHORT)
                        .show();
            } else {
                Toast.makeText(getApplication(), "OFF", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    });
    return true;
}
Ayush
  • 3,989
  • 1
  • 26
  • 34
Vattic
  • 301
  • 4
  • 9
12

As mentioned above, you can't add toggle button to the menu. You can use the android:checkable property in your menu item to handle the two states.

Something like:

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

PS: Copied the code from here.

Or you can just update your item icon on click event to show the two states with item.setIcon(yourDrawable));

Community
  • 1
  • 1
Rami
  • 7,879
  • 12
  • 36
  • 66
  • I have tried this code before and I got this error: `java.lang.NullPointerException: Attempt to invoke interface method 'android.view.MenuItem android.view.MenuItem.setChecked(boolean)' on a null object reference` – The Time Jul 14 '15 at 09:00
  • Check your "menu.xml", you must have an item with "checkable_menu" as id – Rami Jul 14 '15 at 09:45
  • can I use in the if condtion it in this wasy `if (item.isChecked()) {}else{}` instead of `isChecked = !item.isChecked(); item.setChecked(isChecked);`? – The Time Jul 14 '15 at 10:05
  • Yes, but don't forget to update *isChecked* variable and *item.setChecked(newValue);* inside the IF and ELSE. – Rami Jul 14 '15 at 10:11
  • Please can you take a look at my edit code. How can I set the checkbox checked as default? – The Time Jul 14 '15 at 10:31
  • I already mentioned that in my answer, you need to save the state in a class variable (named *isChecked* in my code) and in *onPrepareOptionsMenu()* you set the value of your item *checkable.setChecked(isChecked);*. So if you want it checked by default, just initializes your variable with *true* instead of *false* (*private boolean isChecked = false;* ) – Rami Jul 14 '15 at 10:38
2

You cannot put any widget in <menu> and expect it to work. What you can put there is documented here and it's basically limited to menu <item> and <group>. No buttons, toggles and other widgets are supported. If that would be sufficient you can use android:checkable on the <item> or use old-skool approach and alter menu item depending on the state (if service is on, then your item should read turn service off and vice versa).

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
0

Menu resources are distinct from conventional layouts; you cannot simply add widgets into them and expect them to work. The only elements allowed inside a menu resource is <item> or <group>.

Using a custom layout inside a menu isn't possible, I'm afraid. You may instead want to replace the entire menu with a PopupWindow, and supply your layouts there instead.

You may want to consider two alternatives:

  • Using a conventional menu entry as a toggle, or
  • Placing the ToggleButton immediately inside the Actionbar/Toolbar, instead of inside the menu.
Paul Lammertsma
  • 37,593
  • 16
  • 136
  • 187
0

In the menu xml you add items not widgets (no buttons/textviews etc)

You simply specify an ID and an ICON for the item, then inflate them in your activities onCreateOptionsMenu() method.

then there is a method called onOptionsItemSelected(MenuItem item) check items id against the ids your expecting.

If its equal to your toggle service option determine service state and alter, if you want to have a toggle button function you can use item.setIcon(drawable) here.

Hughzi
  • 2,470
  • 1
  • 20
  • 30