提问者:小点点

如何在特定菜单项之间添加分隔线?


我在操作栏(实际上是工具栏)中有一个菜单项,单击该菜单项时,会显示一个可供选择的项目列表,类似于单选按钮:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:icon="@drawable/..."
        android:title="@string/..."
        app:showAsAction="always">
        <menu>
            <group
                android:id="@+id/..."
                android:checkableBehavior="single">
                <item .../>
                <item .../>
                <item .../>
            </group>
        </menu>
    </item>
</menu>

我需要在这个项目列表下面放一个项目,在它和列表之间有一个分隔符。与材料设计指南所示类似(摘自此处):

编辑:下面是我想做的事情的草图:

我找不到办法。

我找到的唯一可能的解决方案是:

>

  • 更改活动主题(此处),但这也会影响活动的其他菜单项

    方法,当菜单项出现在操作栏上时,在它们之间放置分隔符,但在这里它们不出现在工具栏本身上。它们出现在所选项目的弹出菜单上。

    我尝试了在列表和多余的项目之间放假项目,也尝试了放一个组,一个空组,甚至尝试了各种属性。

    可悲的是,什么都没起作用。

    如何在动作项弹出菜单的特定项之间添加分隔符?

    也许我需要在点击执行事项时创建一个自定义弹出菜单(像这里)?如果是这样,我如何在那里的特定项目之间放置一个分隔符?也许使用微调器作为执行事项?


  • 共3个答案

    匿名用户

    你应该使用动作布局

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        tools:context=".LandingActivity">
        <item
            android:id="@+id/action_cart"
            android:title="cart"
            android:actionLayout="@layout/cart_update_count"
            android:icon="@drawable/shape_notification"
            app:showAsAction="always"/>
    </menu>
    

    然后动作布局可以有带分隔符的文本视图。

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <View
            android:id="@+id/divider"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/divider"/>
    
        <TextView
            android:id="@android:id/text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:attr/selectableItemBackground"
            android:gravity="center_vertical"          
            android:textAppearance="?attr/textAppearanceListItemSmall"/>
    
    </LinearLayout>
    

    然后可以在代码中添加click侦听器

    匿名用户

    从SDK版本28开始,您可以使用菜单。setGroupDividerEnabled(布尔)。如果您使用的是上下文菜单(ContextMenu),则只有SDK 28支持此功能,但在创建选项菜单(onCreateOptionsMenu()中使用时,菜单比较(MenuCompat)提供向后兼容性。

    这将在每个不同groupId的操作之间添加一个分隔符,如下所示为0和1:

    menu.add(0, getAdapterPosition(), action1, R.string.action1);
    menu.add(1, getAdapterPosition(), action2, R.string.action2);
    menu.setGroupDividerEnabled(true); 
    
    // Or for MenuCompat < SDK 28:
    MenuCompat.setGroupDividerEnabled(menu, true);
    

    这里的文档:https://developer.android.com/reference/android/view/Menu#setGroupDividerEnabled(boolean)

    编辑:asker要求的示例代码:

    这是我目前在应用程序中使用的代码,位于RecyclerView适配器中。它也应该与菜单实现配合使用。由于您是通过XML定义菜单的,只要您引用菜单资源,下面的内容也适用于您。结果如下:

    覆盖onCreateContextMenu或您菜单的相关onCreate...方法,如下所示:

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        menu.setHeaderTitle(getStr(R.string.actions_title));
    
        // Groups 0 and 1, first parameter for menu.add()
        menu.add(0, getAdapterPosition(), 0, R.string.homescreen);
        menu.add(0, getAdapterPosition(), 1, R.string.lockscreen);
        menu.add(0, getAdapterPosition(), 2, R.string.wpLocation_both);
        menu.add(1, getAdapterPosition(), 3, R.string.action_download);
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            menu.setGroupDividerEnabled(true);  // This adds the divider between groups 0 and 1, but only supported on Android 9.0 and up.
        }
    }
    

    匿名用户

    好的,我找到了一个很好的解决方法,但我不确定样式应该是这样的。这就是我错过的:

    1. 项目的背景在微调器弹出窗口的背景之上,我不确定这是否是正确的说法。
    2. 我为微调器的弹出使用了支持库的白色背景。我想应该有更好的方法让它变成白色。
    3. 我需要知道分隔符的正确样式是什么。目前我使用了一个简单的
    4. 动作栏项样式缺失。我只是用了一个简单的ImageView,我认为它应该是不同的。
    5. 出于某种原因,在某些Android版本(可能是Lollipop和以下版本)上,项目的背景看起来是黑色而不是白色。
    6. 微调器有时可能会遇到setOnItemSelectedListener的问题,不确定何时出现。

    主要活动

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        final MenuItem item = menu.findItem(R.id.action_settings);
        final Spinner spinner = ((Spinner) MenuItemCompat.getActionView(item));
        SimpleImageArrayAdapter adapter = new SimpleImageArrayAdapter(this);
        spinner.setAdapter(adapter);
        return true;
    }
    
    public class SimpleImageArrayAdapter extends ArrayAdapter<String> {
        private final String[] items = {"item 1", "item 2", "item 3", "extra item"};
    
        public SimpleImageArrayAdapter(Context context) {
            super(context, 0);
        }
    
        @Override
        public int getCount() {
            return items.length;
        }
    
        @Override
        public String getItem(final int position) {
            return items[position];
        }
    
        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            View rootView = convertView == null ? LayoutInflater.from(getContext()).inflate(R.layout.spinner_item, parent, false) : convertView;
            TextView tv = (TextView) rootView.findViewById(android.R.id.text1);
            tv.setTextColor(0xff000000);
            tv.setText(items[position]);
            boolean isLastItem = position == getCount() - 1;
            rootView.findViewById(R.id.action_divider).setVisibility(isLastItem ? View.VISIBLE : View.GONE);
            rootView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            return rootView;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            //this is the view that's shown for the spinner when it's closed
            ImageView iv = new ImageView(getContext());
            iv.setImageResource(android.R.drawable.ic_menu_add);
            int viewSize = getDimensionFromAttribute(MainActivity.this, android.support.v7.appcompat.R.attr.actionBarSize);
            iv.setLayoutParams(new ViewGroup.LayoutParams(viewSize, viewSize));
            iv.setScaleType(ScaleType.CENTER_INSIDE);
            iv.setBackgroundResource(getResIdFromAttribute(MainActivity.this, R.attr.selectableItemBackground));
            return iv;
        }
    
    }
    
    public static int getResIdFromAttribute(final Activity activity, final int attr) {
        if (attr == 0)
            return 0;
        final TypedValue typedValue = new TypedValue();
        activity.getTheme().resolveAttribute(attr, typedValue, true);
        return typedValue.resourceId;
    }
    
    public static int getDimensionFromAttribute(final Context context, final int attr) {
        final TypedValue typedValue = new TypedValue();
        if (context.getTheme().resolveAttribute(attr, typedValue, true))
            return TypedValue.complexToDimensionPixelSize(typedValue.data, context.getResources().getDisplayMetrics());
        return 0;
    }
    

    res/菜单/menu_main.xml

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          xmlns:tools="http://schemas.android.com/tools"
          tools:context="com.example.user.myapplication.MainActivity">
        <item
            android:id="@+id/action_settings"
            android:actionLayout="@layout/spinner"
            android:title=""
            app:actionLayout="@layout/spinner"
            app:showAsAction="always"
            />
    </menu>
    

    res/layout/spinner\u项。xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/action_divider"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/divider"/>
    
        <TextView
            android:id="@android:id/text1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:attr/selectableItemBackground"
            android:gravity="center_vertical"
            android:minHeight="?attr/listPreferredItemHeightSmall"
            android:paddingEnd="?attr/listPreferredItemPaddingRight"
            android:paddingLeft="?attr/listPreferredItemPaddingLeft"
            android:paddingRight="?attr/listPreferredItemPaddingRight"
            android:paddingStart="?attr/listPreferredItemPaddingLeft"
            android:textAppearance="?attr/textAppearanceListItemSmall"/>
    
    </LinearLayout>
    

    分辨率/布局/微调器。xml

    <?xml version="1.0" encoding="utf-8"?>
    <Spinner
        android:id="@+id/spinner"
        style="@style/SpinnerWithoutArrow"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    

    分辨率/值/样式。xml

    <style name="SpinnerWithoutArrow" parent="@style/Widget.AppCompat.Spinner">
        <item name="android:background">@null</item>
        <item name="android:popupBackground">@drawable/abc_popup_background_mtrl_mult</item>
    </style>
    

    res/drawable/divider。xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <size
            android:height="1dp"/>
        <solid android:color="#FFff0000" />
    </shape>