【问题标题】:How to set a listener to a switch in the action bar?如何将监听器设置为操作栏中的开关?
【发布时间】:2014-01-15 00:58:03
【问题描述】:

我有这个菜单布局:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/actionBarSave"
        android:showAsAction="always"
        android:scaleType="fitXY"
        android:icon="@drawable/save_33x26"
        style="@style/ActionButtonStyle"
        android:title="save" />
    <item android:id="@+id/actionBarLoad"
        android:showAsAction="always"
        android:icon="@drawable/load70x24"
        android:scaleType="fitXY"
        android:title="load" />
    <item android:id="@+id/actionBarDelete"
        android:showAsAction="always"
        android:scaleType="fitXY"
        android:icon="@drawable/delete_enabled"
        android:title="delete" />
    <item
        android:id="@+id/actionBarSoundSwitch"
        android:title="soundswitch"
        android:layout_centerInParent="true"
        android:scaleType="fitXY"
        android:showAsAction="always"
        android:actionLayout="@layout/sound_switch" /> 
</menu>

sound_switch 布局文件:

<?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/soundSwitch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SFX"
        android:layout_centerInParent="true" />

</RelativeLayout>

这是我尝试将 OnCheckedChangeListener 添加到开关的 java 代码:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        soundSwitch = (Switch)findViewById(R.id.actionBarSoundSwitch);
        soundSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener(){

            @Override
            public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
                soundOn = arg1;
            }

        });
        switch (item.getItemId()) {
            case R.id.actionBarSave:
                onSave();
                return true;
            case R.id.actionBarLoad:
                onLoad();
                return true;
            case R.id.actionBarDelete:
                onDelete();
                return true;
            case R.id.actionBarSoundSwitch:
                onSound();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

没有 logcat 错误,但我检查过,监听器不工作。任何想法为什么?

【问题讨论】:

  • 有人可以回复此评论,以便我至少知道有人正在处理它吗?我仍在努力,但没有任何工作......
  • 听起来您在添加操作栏切换按钮时使用了错误的路径...
  • @shoerat 谢谢你的回复,我可能是因为它不起作用,你有什么想法吗?
  • 作为答案发布,希望对您有所帮助。

标签: java android


【解决方案1】:
<item
        android:title="Switch"
        app:actionLayout="@layout/switch_item"
        app:showAsAction="always" />

如果我们去“@layout/switch_item”我们会发现

<androidx.appcompat.widget.SwitchCompat
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

我在 SwitchCompat 中添加了一个 id 标签

android:id="@+id/switch_darkmode"

然后在activity中添加CheckedChanged Listener

SwitchCompat darkmode=findViewById(R.id.switch_darkmode);
darkmode.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        System.out.println("SWITCH TOGGLED");
    }
});

【讨论】:

    【解决方案2】:

    试试这个

     <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/actionBarSave"
        android:showAsAction="always"
        android:scaleType="fitXY"
        android:icon="@drawable/save_33x26"
        style="@style/ActionButtonStyle"
        android:title="save" />
    <item android:id="@+id/actionBarLoad"
        android:showAsAction="always"
        android:icon="@drawable/load70x24"
        android:scaleType="fitXY"
        android:title="load" />
    <item android:id="@+id/actionBarDelete"
        android:showAsAction="always"
        android:scaleType="fitXY"
        android:icon="@drawable/delete_enabled"
        android:title="delete" />
    <item
        android:id="@+id/actionBarSoundSwitch"
        android:title="soundswitch"
        android:layout_centerInParent="true"
        android:scaleType="fitXY"
        android:actionViewClass="android.widget.ImageButton"
        android:showAsAction="always"
        android:actionLayout="@layout/sound_switch" /> 
    </menu>
    

    //--------------------------------------------- -------------

       public boolean onCreateOptionsMenu(Menu menu) {
       super.onCreateOptionsMenu(menu);
       getMenuInflater().inflate(R.menu.menu_search, menu);
     soundSwitch = (Switch)findViewById(R.id.actionBarSoundSwitch);
       soundSwitch .setOnClickListener(new View.OnClickListener() {
    
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
        }
    });
    return true;
    

    }

    【讨论】:

      【解决方案3】:

      在 onPrepareOptionMenu 中试试这个

      MenuItem item = menu.findItem(R.id.actionBarSoundSwitch);  
      soundSwitch = (Switch)item.getActionView().findViewById(R.id.soundSwitch);
      

      【讨论】:

        【解决方案4】:

        由于没有信息说明您将在何处添加ActionBar 开关按钮以及您所针对的 API 级别,我只是发布了我将如何添加一个。

        AndroidManifest.xml:

        <?xml version="1.0" encoding="utf-8"?>
        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
            package="com.example.actionbarswitch"
            android:versionCode="1"
            android:versionName="1.0" >
        
            <uses-sdk
                android:minSdkVersion="14"
                android:targetSdkVersion="19" />
        
            <application
                android:allowBackup="true"
                android:icon="@drawable/ic_launcher"
                android:label="@string/app_name"
                android:theme="@style/AppTheme" >
                <activity
                    android:name="com.example.actionbarswitch.MainActivity"
                    android:label="@string/app_name" >
                    <intent-filter>
                        <action android:name="android.intent.action.MAIN" />
        
                        <category android:name="android.intent.category.LAUNCHER" />
                    </intent-filter>
                </activity>
            </application>
        
        </manifest>
        

        MainActivity.java:

        package com.example.actionbarswitch;
        
        import android.app.ActionBar;
        import android.app.Activity;
        import android.os.Bundle;
        import android.util.Log;
        import android.view.Gravity;
        import android.view.Menu;
        import android.widget.CompoundButton;
        import android.widget.Switch;
        
        public class MainActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
            private static final String TAG = "ActionBarSwitch";
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        
                Switch actionBarSwitch = new Switch(this);
        
                ActionBar actionBar = getActionBar();
                actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM);
                actionBar.setCustomView(actionBarSwitch, new ActionBar.LayoutParams(
                        ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT,
                        Gravity.CENTER_VERTICAL | Gravity.END));
        
                actionBarSwitch.setOnCheckedChangeListener(this);
            }
        
        
            @Override
            public boolean onCreateOptionsMenu(Menu menu) {
                getMenuInflater().inflate(R.menu.main, menu);
                return true;
            }
        
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                Log.i(TAG, "isChecked? " + isChecked);
            }
        }
        

        LogCat 输出:

        I/ActionBarSwitch(10081): isChecked? true
        I/ActionBarSwitch(10081): isChecked? false
        

        屏幕截图(取自 Nexus5):

        希望这会有所帮助。

        【讨论】:

          【解决方案5】:

          确保首先使用R.menu.mymenuxmlonPrepareOptionsMenu 中扩展菜单,然后使用菜单而不是活动上下文来查找视图

          soundSwitch = (Switch)menu.findViewById(R.id.actionBarSoundSwitch);
          

          【讨论】:

          • 我收到findViewById is undefined for type Menu
          • 另外,我觉得这可能是错误的。每次打开菜单时都会调用onPrepareOptionsMenu。每次打开菜单时都寻找视图并设置监听器是不明智的。我认为这应该全部放在只调用一次的onCreateOptionsMenu 中,但我仍然遇到与我之前的评论相同的错误。顺便说一句,谢谢您的回复。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-16
          • 2020-12-25
          相关资源
          最近更新 更多