【问题标题】:How to add a switch to android action bar?如何在android操作栏上添加一个开关?
【发布时间】:2018-09-17 20:54:18
【问题描述】:

我想添加一个类似于 jellybean 原生外观的按钮开关。 (视图顶部的蓝色/灰色开关)

文档显示了如何在那里创建菜单或添加图标,但没有说明如何添加自定义元素。例如。一个开关。 http://developer.android.com/guide/topics/ui/actionbar.html

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    为开关switch_layout.xml 创建一个布局。菜单的自定义布局应始终为RelativeLayout

    <?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/switchForActionBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="" />
    
    </RelativeLayout>
    

    然后,在您的mainmenu.xml 中添加如下项目

    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <item
            android:id="@+id/myswitch"
            android:title=""
            android:showAsAction="always"
            android:actionLayout="@layout/switch_layout"
        />   
    </menu>
    

    在你的活动中,像往常一样给mainmenu.xml充气

    getMenuInflater().inflate(R.menu.mainmenu, menu);
    return true;
    

    【讨论】:

    • 嘿,“菜单的自定义布局应始终为 RelativeLayout”。是否有任何文档状态?
    • 您应该将android:layout_centerVertical="true" 添加到Switch 以使其与标题具有相同的高度
    • 不要忘记添加“setHasOptionsMenu(true);”让片段强制调用 onCreateOptionsMenu。
    • 如果开关不可见,则为actionLayoutshowAsAction 使用app 命名空间
    • 我正在使用 appcompat,并且我将 app 命名空间用于 actionLayout 和 showAsAction,但我无法处理它对 onOptionsItemSelected 方法的点击?怎么办?
    【解决方案2】:

    终于解决了我的问题:对于那些使用新 AppCompat 的用户,您应该在开关布局上使用 android.support.v7.widget.SwitchCompat 而不是 Switch...否则,它不会显示在 ActionBar 上(假设你也在使用 AppCompat ActionBar),好吧,actionLayout 属性不起作用,它必须在代码中设置。

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/switchView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
    
        <android.support.v7.widget.SwitchCompat
            android:id="@+id/switchForActionBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="" />
    
    </RelativeLayout>
    

    然后在代码中设置布局:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        MenuItem item = menu.findItem(R.id.on_off_switch);
        item.setActionView(R.layout.on_off_switch);
        return true;
    }
    

    【讨论】:

    • 使用SwitchCompat 有另一个优点:开关以更新的外观显示(例如材料设计)。
    • 为什么大家都在RelativeLayout上使用android:orientation="horizontal"
    • @zackygaurav 作为我的测试,它不需要使用RelativeLayout,我使用的是LinearLayout,它可以完美运行。
    【解决方案3】:

    如果小部件没有出现在操作栏中,可能是因为您将 appCompat 用于操作栏。解决这个在你的 menu.xml 中的“showAsAction”和“actionLayout”前面切换“android:”到“app:”的问题

    将项目添加到 xml,用 app: 代替 android:

    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
                <item
                    android:id="@+id/myswitch"
                    android:title=""
                    app:showAsAction="always"
                    app:actionLayout="@layout/switch_layout"
                />   
            </menu>
    

    制作您用于“app:actionLayout”的布局
    switch_layout

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

    像往常一样在 ActionBarActivity 中扩展菜单

       getMenuInflater().inflate(R.menu.mainmenu, menu);
        return true;
    

    如果没有出现,这应该会使开关出现在您的操作栏中。

    【讨论】:

    • 这是对上述答案的微妙但极好的简化/补充!
    • 这样的小细节很容易被监督而忘记调整。我总是花几个小时试图找出错误。现在,如果菜单中没有显示某些内容,我有一个经验法则来检查命名空间。
    • 我知道它已经很久了,但这个答案对我有用,现在的问题是我如何获得开关以便我可以通过编程方式附加一个监听器?
    【解决方案4】:

    对于那些想要添加的人,

    检查更改监听器到同一个开关

    科特林

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)
        val item = menu!!.findItem(R.id.my_switch_item)
        item.setActionView(R.layout.switch_layout)
    
        val mySwitch = item.actionView.findViewById(R.id.switch_id)
        mySwitch.setOnCheckedChangeListener(object : CompoundButton.OnCheckedChangeListener{
            override fun onCheckedChanged(p0: CompoundButton?, isChecked: Boolean) {
                // do what you want with isChecked
            }
        })
    
        return true
    }
    

    Java

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        MenuItem item = menu.findItem(R.id.my_switch_item);
        item.setActionView(R.layout.switch_layout);
    
        Switch mySwitch = item.getActionView().findViewById(R.id.switch_id);
        mySwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
             @Override
             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                      // do something based on isChecked
             }
        });
        return true;
    }
    

    附:您可以更改对 Switch 或 SwitchCompat 的引用

    【讨论】:

      【解决方案5】:

      Ezequiel 提供的解决方案很棒而且很有效。这是另一种方法:

      定义您的自定义布局:

      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" >
          <Switch
              android:id="@+id/actionbar_switch"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="" />
      </RelativeLayout>
      

      以编程方式膨胀它:

      ActionBar actionBar = getSupportActionBar();
      actionBar.setCustomView(R.layout.actionbar_top);
      actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_CUSTOM);
      ...
      Switch button = (Switch) findViewById(R.id.actionbar_switch);
      

      【讨论】:

      • 哇...这解决了我的问题!!!我似乎无法使用 Ezequiel 的解决方案,但这是我的解决方案!也许它与我用作 ActionBar 的新工具栏有关?无论如何,谢谢你!注意:这似乎与我希望它作为菜单的自定义视图的原始方法不同......但是有没有办法让这个自定义视图与操作栏的右侧对齐?
      • 想出答案并分享给那些在同一条船上的人。
      • @VuNguyen 太棒了!我仍在处理它,因为我在 Fragment 中有这个 ActionBar,findViewById 返回 null,解决后会更新:D
      • @arthursfreire 你好。我不确定您的代码是什么样子,但请给 onCreate 方法一个高峰,特别是在此处的第 80 行之后github.com/fabriph/peer-instruction/blob/master/…
      • @arthursfreire 这是我自己编写的全功能代码,我仍在从事该项目,支持 SDK 16 到 21。
      猜你喜欢
      • 2017-06-11
      • 1970-01-01
      • 2013-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      相关资源
      最近更新 更多