Add toggle button to the menu to stop and start service
Solution 1
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));
Solution 2
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!
It is rather big but you can adjust its size, obviously
Solution 3
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;
}
Solution 4
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).
The Time
Updated on July 12, 2022Comments
-
The Time almost 2 years
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 almost 9 yearsI 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
-
Rami almost 9 yearsCheck your "menu.xml", you must have an item with "checkable_menu" as id
-
The Time almost 9 yearscan I use in the if condtion it in this wasy
if (item.isChecked()) {}else{}
instead ofisChecked = !item.isChecked(); item.setChecked(isChecked);
? -
Rami almost 9 yearsYes, but don't forget to update isChecked variable and item.setChecked(newValue); inside the IF and ELSE.
-
The Time almost 9 yearsPlease can you take a look at my edit code. How can I set the checkbox checked as default?
-
Rami almost 9 yearsI 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; )
-
Antek about 6 yearswasn't the OP's intention to put a toggle switch in the drop-down menu?