J'ai un élément de menu dans la barre d'action (barre d'outils en fait) qui, lorsque vous cliquez dessus, affiche une liste d'éléments à choisir, semblable aux boutons radio:
<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>
J'ai besoin de mettre un élément en dessous de cette liste d'éléments, qui aura un séparateur entre celui-ci et la liste. Similaire à ce que les directives de conception des matériaux montrent (extrait de ici ):
EDIT: voici un croquis de ce que je veux faire:
Je ne trouve pas de moyen de le faire.
Les seules solutions possibles que j'ai trouvées sont:
changer le thème de l'activité ( ici ), mais cela affectera également les autres éléments de menu de l'activité
méthodes pour mettre un séparateur entre les éléments de menu lorsqu'ils apparaissent dans la barre d'action, mais ici, ils n'apparaissent pas sur la barre d'outils elle-même. Ils apparaissent dans un menu contextuel d'un élément sélectionné.
J'ai essayé de mettre de faux articles entre la liste et l'élément supplémentaire, et j'ai également essayé de mettre un groupe, un groupe vide et même essayé divers attributs.
Malheureusement, rien n'a fonctionné.
Comment puis-je ajouter un séparateur entre des éléments spécifiques du menu contextuel d'un élément d'action?
Peut-être que je dois créer un menu contextuel personnalisé en cliquant sur l'élément d'action (comme ici )? Si oui, comment puis-je y placer un séparateur entre des éléments spécifiques? Peut-être utiliser un Spinner comme élément d'action?
OK, j'ai trouvé une solution de contournement agréable, mais je ne suis pas sûr que le style devrait être de cette façon. C'est ce qui me manque:
MainActivity
@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/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_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/layout/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/values / 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/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>
Vous devez utiliser la disposition des actions
<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>
puis la disposition de l'action peut avoir la vue texte avec diviseur.
<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>
alors vous pouvez ajouter l'écouteur de clic dans le code
Solution super simple qui a fonctionné pour moi:
Définissez un dessinable pour l'arrière-plan:
<?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>
puis dans les styles utiliser l'arrière-plan:
<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>
Cela peut être fait en utilisant une fenêtre contextuelle et une vue de liste. Dans votre affichage de liste, vous pouvez avoir différents types d'affichage, tels que l'élément de menu et le séparateur.
Je liste le code pour la partie de la fenêtre contextuelle:
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);
Ensuite, vous pouvez utiliser la méthode suivante pour afficher la fenêtre contextuelle:
PopupWindowCompat.showAsDropDown(mPopupWindow, parent, x, y, gravity);
Dans l'adaptateur pour l'affichage de liste, vous pouvez remplacer getViewTypeCount () et getItemViewType () pour prendre en charge à la fois la disposition des éléments de menu et la disposition du diviseur, vous pouvez également ajouter tout type de vue dont vous avez besoin.
Voici un instantané dans mon application:
Je l'ai fait de cette façon:
Capture d'écran de référence:
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>
Code 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;
}
});
}
J'espère que cela vous aidera.