Je souhaite créer un menu contextuel personnalisé du type Twitter sous Android, par exemple, avec élément et image, mais je ne sais pas quel composant est utilisé pour cela.
Dans le site Web Material Design, Google présente cette solution . Je pense donc qu’il existe une solution native pour y parvenir.
J'ai essayé avec Menu contextuel , mais je ne trouve pas comment personnaliser la disposition de cette vue de cette manière.
vous pouvez utiliser ListPopupWindow pour soumettre votre adaptateur personnalisé, via lequel vous pouvez contrôler la présentation de chaque ligne de la ListPopupWindow
. Comme pour une PopupWindow
normale, vous devez fournir une vue d'ancrage et appeler setContentWidth
sur l'instance de ListPopupWindow
, qui définit la largeur de la fenêtre contextuelle en fonction de la taille de son contenu. C'est un petit prix que vous devez payer, mais pour un petit jeu de données, ce n'est pas grave. J'ai cette méthode utilitaire pour récupérer la largeur maximale de la ligne:
public int measureContentWidth(ListAdapter adapter) {
int maxWidth = 0;
int count = adapter.getCount();
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
View itemView = null;
for (int i = 0; i < count; i++) {
itemView = adapter.getView(i, itemView, this);
itemView.measure(widthMeasureSpec, heightMeasureSpec);
maxWidth = Math.max(maxWidth, itemView.getMeasuredWidth());
}
return maxWidth;
}
Il existe un widget appelé PopupMenu
qui est essentiellement un menu ancré dans une vue spécifique. Un inconvénient est qu’il n’affiche pas les icônes par défaut.
Cependant, vous pouvez utiliser la réflexion et appeler setForceShowIcon
pour les révéler. Le code dont vous avez besoin est:
Etant donné que PopupMenu
est ancré dans une vue spécifique, votre élément ActionBar
a un attribut actionLayout
. Cette disposition (action_item.xml
) peut être aussi simple que:
<Button
xmlns:Android="http://schemas.Android.com/apk/res/Android"
style="?attr/actionButtonStyle"
Android:layout_gravity="center"
Android:text="Show popup"
Android:textStyle="bold"
Android:textSize="12sp"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"/>
ActionBar
style de menu qui contient votre élément avec la disposition ci-dessus
<menu
xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item
Android:id="@+id/popup_item"
Android:title="Show popup"
Android:showAsAction="always"
Android:actionLayout="@layout/action_item"/>
</menu>
Votre popup_menu.xml
, la disposition que vous allez gonfler pour votre PopupMenu
<menu
xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item
Android:id="@+id/item1"
Android:title="Item1"
Android:icon="@mipmap/ic_launcher"/>
</menu>
Et enfin, code pour effectuer le gonflage quand un élément ActionBar
est cliqué
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add_item:
PopupMenu popup = new PopupMenu(this, item.getActionView());
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popup.getMenu());
// Use reflection to invoke setForceShowIcon
try {
Field[] fields = popup.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(popup);
Class<?> classPopupHelper = Class
.forName(menuPopupHelper.getClass().getName());
Method setForceIcons = classPopupHelper
.getMethod("setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
popup.show();
return true;
}
return super.onOptionsItemSelected(item);
}
Notez que pour obtenir ce texte multiligne dans un menu, vous devez également utiliser une variable actionLayout
pour vos éléments de menu contextuels.
Utilisez un fragment de liste contextuelle . La bonne chose à propos des fragments est que vous pouvez facilement les animerIntroduction au fragment )
Si vous souhaitez contrôler entièrement le contenu de la fenêtre contextuelle, consultez la section Fragment de la boîte de dialogue
J'ai le même problème. Mais finalement, j'ai trouvé avec ma propre solution que je vous partage mon code. J'espère que cela vous aidera.
popupWindowDogs = popupWindowDogs(); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub // popupWindowDogs.showAsDropDown(v, -5, 0); popupWindowDogs().showAtLocation(v, Gravity.CENTER, 0, 0); } }); // Detect touched area detector = new SimpleGestureFilter(this, this);
}
public PopupWindow popupWindowDogs() { // initialize a pop up window type PopupWindow popupWindow = new PopupWindow(this); // the drop down list is a list view final ListView listView = new ListView(this); // set our adapter and pass our pop up window contents listView.setAdapter(dogsAdapter(popUpContents)); // listView.setBackgroundColor(Color.DKGRAY); listView.setBackgroundResource(R.drawable.ss4); listView.setPadding(0, 0, 0, 10); listView.setDivider(null); try { listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { View c = listView.getChildAt(0); String cc = listView.getChildAt(0).toString(); int scrolly = -c.getTop() + listView.getFirstVisiblePosition() * c.getHeight(); /* * Toast.makeText(getApplicationContext(), scrolly + "", Toast.LENGTH_SHORT) * .show(); */} @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } catch (Exception e) { Toast.makeText(getApplicationContext(), e.toString() + "", Toast.LENGTH_SHORT) .show(); } listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3) { try { // TODO Auto-generated method stub Context mContext = v.getContext(); Swipetouch mainActivity = ((Swipetouch) mContext); // add some animation when a list item was clicked Animation fadeInAnimation = AnimationUtils.loadAnimation(v.getContext(), Android.R.anim.fade_in); fadeInAnimation.setDuration(10); v.startAnimation(fadeInAnimation); // dismiss the pop up mainActivity.popupWindowDogs.dismiss(); // get the text and set it as the button text String val = (String) arg0.getItemAtPosition(arg2); // Toast.makeText(mContext, val, Toast.LENGTH_SHORT).show(); if (val.equals("Signup Now")) { Intent ii = new Intent(getApplicationContext(), Registration.class); startActivity(ii); stopService(new Intent(Swipetouch.this, MyService.class)); stopService(new Intent(Swipetouch.this, MyService.class)); } else if (val.equals("Login")) { Intent ii = new Intent(getApplicationContext(), MyLoginActivity.class); startActivity(ii); stopService(new Intent(Swipetouch.this, MyService.class)); } else if (val.equals("Exit")) { finish(); stopService(new Intent(Swipetouch.this, MyService.class)); } else if (val.equals("Friends")) { Intent ii = new Intent(getApplicationContext(), MyLoginActivity.class); startActivity(ii); } else if (val.equals("Exit")) { stopService(new Intent(Swipetouch.this, MyService.class)); finish(); } } catch (Exception e) { Toast.makeText(Swipetouch.this, e.toString(), Toast.LENGTH_SHORT).show(); } } }); // some other visual settings popupWindow.setFocusable(true); popupWindow.setWidth(250); // popupWindow.setHeight(300); popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); // set the list view as pop up window content // SET WALLPAPER IMAGE /* * popupWindow.setBackgroundDrawable(getWallpaper()); popupWindow.setHeight(300); */ // layout.setBackgroundResource(R.drawable.sshadow); // layout.setBackgroundColor(Color.TRANSPARENT); // popupWindow.setContentView(layout); popupWindow.setBackgroundDrawable(new ColorDrawable( Android.graphics.Color.TRANSPARENT)); popupWindow.setContentView(listView); return popupWindow; }
try {
Java.lang.reflect.Field[] fields = popup.getClass().getDeclaredFields();
for (Java.lang.reflect.Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(popup);
Class<?> classPopupHelper = Class
.forName(menuPopupHelper.getClass().getName());
Method setForceIcons = classPopupHelper
.getMethod("setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
Ce code fonctionne dans mon application.
Essaye ça :-
<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=".LocationDetailsActivity">
<item xmlns:tools="http://schemas.Android.com/tools"
Android:icon="@Android:drawable/ic_menu_mapmode"
app:showAsAction="ifRoom"
Android:title="@string/title_of_menu"
tools:context=".LocationDetailsActivity">
//the menu list with icon
<menu>
<item
Android:id="@+id/action_map_type_normal"
Android:orderInCategory="100"
Android:icon="some_icon" //place your icon here
Android:title="Vacation spots" />
<item
Android:id="@+id/action_map_type_satellite"
Android:orderInCategory="100"
Android:icon="some_icon" //place your icon here
Android:title="Friends and family" />
<item
Android:id="@+id/action_map_type_hybrid"
Android:orderInCategory="100"
Android:icon="some_icon" //place your icon here
Android:title="Restaurants" />
</menu>
</item>
Vous pouvez suivre le tutoriel de ces différents fournisseurs
http://developer.Android.com/guide/topics/ui/actionbar.html
http://www.vogella.com/tutorials/AndroidActionBar/article.html
http://www.androidhive.info/2013/11/Android-working-with-action-bar/
Tous ont d'excellents exemples et le code source pour vous aider
J'espère que cela vous aidera :)
Solution plus facile. Ajoutez ceci juste avant votre méthode .show ().
try {
Field mFieldPopup=popupMenu.getClass().getDeclaredField("mPopup");
mFieldPopup.setAccessible(true);
MenuPopupHelper mPopup = (MenuPopupHelper) mFieldPopup.get(popupMenu);
mPopup.setForceShowIcon(true);
} catch (Exception e) {}