在菜单中添加切换按钮以停止和启动服务。

10

我正在尝试实现从菜单启用用户停止和启动服务的功能,当他点击文本时文本将被更改,所以我想在菜单工具中添加ToggleButton作为选项,但是在我的情况下什么也没有显示。我该如何修复它?

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

编辑:

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

1
我认为你不能在菜单中添加一个切换按钮。 - capt.swag
6个回答

15

很容易。相反,您将在工具栏上拥有切换按钮。

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

这是你的show_protected_switch.xml布局。

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

并且在代码中:

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

输出!

enter image description here

它相当大,但你可以调整它的大小,显然。


1
OP的意图不是在下拉菜单中放置一个切换开关吗? - Antek

14

这里输入图片描述

我知道很久没有回答了,但希望可以帮到某些人 :)

我按照这个链接并更新了一些已实现的解决方案,因为在这些修改之前应用程序会崩溃。

以下是完整的解决方案: 1- 在布局文件夹下创建一个名为switch_layout.xml的新xml文件,并放入以下内容:

<?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- 在位于菜单文件夹下的 main.xml 文件中添加以下菜单项:

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

3- 前往您的活动,下面是onCreateOptionsMenu方法的完整实现:

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

12
如上所述,您无法将切换按钮添加到菜单中。您可以在菜单项中使用android:checkable属性来处理两种状态。

像这样:

菜单


像这样:

菜单

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

活动:

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: 从这里复制了代码。

或者你可以在单击事件中更新项目图标,使用item.setIcon(yourDrawable));来显示两个状态。


我之前尝试过这段代码,但是出现了以下错误:java.lang.NullPointerException: Attempt to invoke interface method 'android.view.MenuItem android.view.MenuItem.setChecked(boolean)' on a null object reference - The Time
请检查您的“menu.xml”文件,其中必须有一个ID为“checkable_menu”的项目。 - Rami
我可以这样在if条件语句中使用 if (item.isChecked()) {}else{},而不是 isChecked = !item.isChecked(); item.setChecked(isChecked); 吗? - The Time
是的,但不要忘记在IF和ELSE内更新isChecked变量和*item.setChecked(newValue);*。 - Rami
请您能否查看一下我的编辑代码。我该如何将复选框设置为默认选中? - The Time
我已经在我的回答中提到了,你需要将状态保存在一个类变量中(在我的代码中命名为isChecked),并在onPrepareOptionsMenu()中设置你的项目值checkable.setChecked(isChecked);。所以如果你想默认选中它,只需用true而不是false(*private boolean isChecked = false;*)初始化你的变量即可。 - Rami

2
您不能在<menu>中放置任何小部件并期望其正常工作。您可以放置的内容在此处有所说明,基本上仅限于菜单<item><group>。不支持按钮、切换和其他小部件。如果这足够使用,您可以在<item>上使用android:checkable,或者使用老式方法根据状态修改菜单项(如果服务已打开,则您的项目应读取关闭服务,反之亦然)。

0

菜单资源与传统布局不同;您不能简单地将小部件添加到其中并期望它们能正常工作。在菜单资源中只允许包含<item><group>元素。

很抱歉,无法在菜单中使用自定义布局。您可以考虑用PopupWindow替换整个菜单,并在其中提供您的布局。

您可以考虑两种替代方案:

  • 将传统的菜单条目用作切换开关,或者
  • 将ToggleButton直接放在Actionbar/Toolbar中,而不是放在菜单中。

0
在菜单xml中,您添加的是项目而不是小部件(如按钮/文本视图等)。
您只需为该项指定ID和ICON,然后在您的活动的onCreateOptionsMenu()方法中填充它们即可。
然后有一个名为onOptionsItemSelected(MenuItem item)的方法,检查项目ID是否与您期望的ID相同。
如果它等于您的切换服务选项,则确定服务状态并进行更改。如果您想要使用切换按钮功能,则可以在此处使用item.setIcon(drawable)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接