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

背景

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

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

我需要把这个项目列表下面的项目,这将有一个分隔线和列表。 类似于材料devise指南(取自这里 ):

在这里输入图像说明

编辑:这是我想要做的草图:

在这里输入图像说明

问题

我找不到办法做到这一点。

我试过了

我find的唯一可能的解决scheme是:

  1. 改变活动的主题( 这里 ),但这也会影响活动的其他菜单项

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

  3. 我试图在列表和额外的项目之间放置假项目,我也试图把一个组,一个空的组,甚至尝试了各种属性。

可悲的是没有工作。

这个问题

我怎样才能添加一个行动项目的popup式菜单的特定项目之间的分隔线?

也许我需要创build一个自定义的popup菜单,当点击行动项目(如这里 )? 如果是这样的话,我该如何在特定项目之间加上分隔线? 也许使用微调作为一个行动项目?

Solutions Collecting From Web of "如何在特定菜单项之间添加分隔线?"

你应该使用行动布局

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

那么你可以在代码中添加点击侦听器

好的,我find了一个很好的解决方法,但我不确定这种样式应该如何。 这就是我想念的:

  1. 项目的背景是在微调的popup窗口的背景之上,我不知道这是否是正确的方式来把它。
  2. 我使用支持库的白色背景作为微调的popup窗口。 我认为应该有一个更好的方法来使它变白。
  3. 我需要知道什么是分隔线的正确的风格。 现在我用了一个简单的
  4. 操作栏项目样式丢失。 我只是使用了一个简单的ImageView,我认为它应该是不同的。
  5. 出于某种原因,在一些Android版本(也许棒棒糖和以下)项目的背景看起来黑而不是白色。
  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 /布局/ spinner_item.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> 

RES /布局/ spinner.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" /> 

RES /值/ styles.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 /抽拉/ 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> 

这可以通过使用popup窗口和列表视图来完成。 在你的列表视图中,你可以有不同的视图types,比如菜单项和分隔符。

我列出了popup窗口部分的代码:

  LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(R.layout.option_menu, null); ListView listView = (ListView) view.findViewById(R.id.listView); listView.setDivider(null); mAdapter = new OptionListAdapter(context, options); listView.setAdapter(mAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //TODO: The code when item is clicked. } }); mPopupWindow = new PopupWindow(context, null, R.attr.popupMenuStyle); mPopupWindow.setFocusable(true); // otherwise on android 4.1.x the onItemClickListener won't work. mPopupWindow.setContentView(view); mPopupWindow.setOutsideTouchable(true); int height = 0; int width = 0; float density = context.getResources().getDisplayMetrics().density; int minWidth = Math.round(196 * density); // min width 196dip, from abc_popup_menu_item_layout.xml int cellHeight = context.getResources().getDimensionPixelOffset(R.dimen.option_height); int dividerHeight = context.getResources().getDimensionPixelOffset(R.dimen.divider_height); final int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); final int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); for (int i = 0; i < mAdapter.getCount(); i++) { Object item = mAdapter.getItem(i); if (item != null) { View childView = mAdapter.getView(i, null, listView); childView.measure(widthMeasureSpec, heightMeasureSpec); height += cellHeight; width = Math.max(width, childView.getMeasuredWidth()); } else { height += dividerHeight; // divider } } width = Math.max(minWidth, width); Drawable background = mPopupWindow.getBackground(); // 9-pitch images if (background != null) { Rect padding = new Rect(); background.getPadding(padding); height += padding.top + padding.bottom; width += padding.left + padding.right; } mPopupWindow.setWidth(width); mPopupWindow.setHeight(height); mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 

然后你可以使用下面的方法来显示popup窗口:

 PopupWindowCompat.showAsDropDown(mPopupWindow, parent, x, y, gravity); 

在用于列表视图的适配器中,可以重写getViewTypeCount()和getItemViewType()以支持菜单项布局和分隔线布局,也可以添加所需的任何视图types。

这是我的应用程序中的快照:

在这里输入图像说明

超级简单的解决scheme,为我解决:

定义一个可绘制的背景:

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@android:color/white"/> <stroke android:width="3dp" android:color="@color/colorPrimary"/> </shape> 

然后在样式中使用背景:

 <style name="bluetooth_popup" parent="@android:style/Widget.DeviceDefault.Light.PopupMenu"> <item name="android:textColor">@color/colorPrimary</item> <item name="android:textStyle">bold</item> <item name="android:textAllCaps">true</item> <item name="android:background">@android:color/transparent</item> <item name="android:itemBackground">@drawable/bluetooth_popup_buttons</item> 

我这样做了:

参考截图:

在这里输入图像说明

style.xml:

  <style name="popup" parent="Widget.AppCompat.ListView.DropDown"> <item name="android:divider">@color/colorPrimary</item> <item name="android:dividerHeight">1dp</item> <item name="android:textColor">@color/colorPrimary</item> <item name="android:itemBackground">@android:color/white</item> </style> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!--- Customize popmenu --> <item name="android:dropDownListViewStyle">@style/popup</item> </style> 

Java代码:

 private void showPopup(View v) { Context wrapper = new ContextThemeWrapper(this, R.style.popup); PopupMenu mypopupmenu = new PopupMenu(wrapper, v); MenuInflater inflater = mypopupmenu.getMenuInflater(); inflater.inflate(R.menu.menu_patient_language, mypopupmenu.getMenu()); mypopupmenu.show(); mypopupmenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { txtPreferredLanguage.setText(item.getTitle().toString()); switch (item.getItemId()) { case R.id.menuEnglish: // Your code goes here break; case R.id.menuFrench: // Your code goes here break; } return false; } }); } 

希望这会帮助你。

现在:

 group1[ item0 item1 item2 ] group1[item3]; 

改成 :

 group1[ item0 item1] group1[item2 item3] 

组有一个divider ; 它喜欢该组可以在item之间添加一个divder ;

如果divider不可用,请尝试background ; 我从来没有用户menu ; 我的猜测