Menu contextuel dans ListView personnalisé

Chère communauté de Stackoverflow!

J'ai besoin d'aide pour résoudre un problème pour lequel je ne pouvais trouver aucune solution.

  • Différence entre cliquer et utiliser Android
  • Comment régler le temps d'affichage du toast inférieur à Toast.LENGTH_SHORT
  • Déni de permission: Accès au service ComponentInfo {...} de pid = -1
  • MPAndroidChart: axe x bas et multiples y-axes
  • Android BLE, caractéristiques de lecture et d'écriture
  • La version d'outils Android SDK 12 a un problème avec Proguard => la conversion d'erreur au format Dalvik a échoué avec l'erreur 1
  • Ce que je veux atteindre:

    J'ai un adaptateur ListView personnalisé. À chaque Listitem, je souhaite ajouter un menu contextuel, similaire à ListView dans l'application Google Play actuelle.

    Capture d'écran de Google Play items

    C'est ce que j'ai essayé: la plupart de mon code provient de ces exemples d' exemples d'Android \ android-19 \ ui \ ActionBarCompat-ListPopupMenu

    CustomFragmentPageAdapter.java :

    // create new fragment mCustomFragment = CustomFragment.newInstance(position); 

    CustomFragment.java

     public class CustomFragment extends ListFragment implements View.OnClickListener{ ... @Override public void onClick(final View v) { v.post(new Runnable() { @Override public void run() { showPopupMenu(v); } }); } private void showPopupMenu(View view) { PopupMenu popup = new PopupMenu(getActivity(), view); popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu()); popup.show(); } 

    CustomArrayAdapter :

     public class CustomAdapter extends ArrayAdapter<WatchListPlayerItem> { ... @Override public View getView(int position, View convertView, ViewGroup parent) { final int pos = position; LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View rowView = inflater.inflate(R.layout.watch_list_row, parent, false); View popupButton = rowView.findViewById(R.id.imgPopUp); popupButton.setTag(getItem(position)); popupButton.setOnClickListener(mFragment); return rowView; } } 

    Popup_menu.xml :

     <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/install" android:title="Install" /> <item android:id="@+id/addtowishlist" android:title="Add to wishlist" /> </menu> 

    Sortie Logcat :

     java.lang.RuntimeException: Failed to resolve attribute at index 6 at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:603) at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:6423) at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:6591) at android.widget.FrameLayout$LayoutParams.<init>(FrameLayout.java:735) ... 

    L'erreur est lancée dans popup.show () dans mon CustomFragment.

    Cette erreur me rend clairement fou et TOUTE aide pour résoudre ce problème est très appréciée!

  • Télécharger Android Progress
  • Pourquoi l'apk non aligné est-il nécessaire?
  • Erreur: Aucune ressource trouvée qui correspond au nom donné (à 'icône' avec la valeur '@ drawable / icône')
  • Affichage des blocages de DialogFragments ICS
  • Aperçu du créateur de studio Android: comment inclure un cadre de périphérique?
  • La meilleure façon de réorganiser les articles dans Android 4+ ListView
  • 7 Solutions collect form web for “Menu contextuel dans ListView personnalisé”

    J'ai finalement trouvé la solution à mon problème, même si je n'ai aucune explication pour laquelle cette solution fonctionne.

    Avec l'importation suivante, j'ai toujours eu l'erreur:

     import android.support.v7.widget.PopupMenu; 

    Cela fonctionne bien avec l'importation suivante:

     import android.widget.PopupMenu; 

    J'ai testé le code fourni par Ric (Merci pour votre aide!) Et le mien. Les deux fonctionnent maintenant. Peut-être quelqu'un a-t-il une explication pour laquelle l'importation importe dans ce cas.

    Créez d'abord un button dans votre élément personnalisé-listview.xml , puis ajoutez le code ci-dessous:

    Button :

     <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_text" android:id="@+id/button1" ... /> 

    classe:

     public class CustomAdapter extends ArrayAdapter<CustomItem> { private static Activity context = null; private final ArrayList<CustomItem> mItemsArrayList; private CustomFragment mFragment; public CustomAdapter(Activity context, ArrayList<CustomItem> itemsArrayList, CustomFragment fragment) { super(context, R.layout.watch_list_row, itemsArrayList); CustomAdapter.context = context; this.mItemsArrayList = itemsArrayList; this.mFragment = fragment; } @Override public View getView(int position, View convertView, ViewGroup parent) { final int pos = position; LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View rowView = inflater.inflate(R.layout.watch_list_row, parent, false); final Button popUp_btn = (Button)rowView.findViewById(R.id.button1); popUp_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final PopupMenu popup = new PopupMenu(context, popUp_btn); popup.getMenuInflater().inflate(R.menu.context_menu, popup.getMenu()); popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { int i = item.getItemId(); if (i == R.id.item1) { //do something return true; } else if (i == R.id.item2){ //do something return true; } else if (i == R.id.item3) { //do something return true; } else { return onMenuItemClick(item); } } }); popup.show(); 

    EDIT: Cela fonctionne bien pour moi:

    TAB1

     public class TAB1 extends Fragment { View view; public TAB1() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.tab1, null); ListView list = (ListView) view.findViewById(android.R.id.list); CustomList adapter = new CustomList(getActivity()); adapter.addAll(); list.setAdapter(adapter); return view; } 

    CustomList :

     public class CustomList extends ArrayAdapter<YourArrayAdapter> { private static Activity context = null; public CustomList(Activity context) { super(context, R.layout.custom_listview, web); CustomList.context = context; } @Override public View getView(final int position, View view, ViewGroup parent) { LayoutInflater inflater = context.getLayoutInflater(); final View rowView = inflater.inflate(R.layout.custom_listview, null, true); //your stuff here final Button popUp_btn = (Button)rowView.findViewById(R.id.button1); popUp_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final PopupMenu popup = new PopupMenu(context, popUp_btn); popup.getMenuInflater().inflate(R.menu.context_menu, popup.getMenu()); popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { int i = item.getItemId(); if (i == R.id.item1) { //do something return true; } else if (i == R.id.item2){ //do something return true; } else if (i == R.id.item3) { //do something return true; } else { return onMenuItemClick(item); } } }); popup.show(); } }); return rowView; } 

    Utilisez -le comme (contexte d'activité) et non contexte d'application ou contexte

      PopupMenu popup = new PopupMenu(this, v); 
      popup = (Button)findViewById(R.id.button); popup.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { PopupMenu popup = new PopupMenu(MainActivity.this,view); popup.getMenuInflater().inflate(R.menu.popup_menu,popup.getMenu()); popup.show(); popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { int id = item.getItemId(); if(id==R.id.install){ show_toast("Install Clicked"); }else{ show_toast("WishList Clicked"); } return true; } }); } }); public void show_toast(String message){ Toast.makeText(this,message,Toast.LENGTH_SHORT).show(); } 

    Remarque:
    N'oubliez pas d'importer ceci …

     import android.support.v7.widget.PopupMenu; import android.view.MenuItem; 

    Je viens d'avoir le même problème lorsque j'ai modifié le style parent de la thème: de

     <style name="MainAppTheme" parent="@style/Theme.AppCompat.Light"> 

    à

     <style name="MainAppTheme" parent="@style/Theme.Base.AppCompat.Light"> 

    Peut-être que votre application utilise le style Theme.Base, qui ne définit pas le 6ème paramètre requis utilisé par PopupMenu. À partir de la question SO Comment utiliser ActionBarActivity avec Theme.Material , Theme.AppCompat extends Theme.Base.AppCompat

    Le code de lignes de Rick fonctionne parfaitement tant que vous importez ce qui suit:

     import android.widget.PopupMenu; 

    Pas celui ci-dessous:

     import android.support.v7.widget.PopupMenu; 

    J'ai corrigé une erreur similaire en passant comme paramètre une activité statique. Par exemple:

     static AppCompatActivity sActivity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sActivity = this; yourLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { PopupMenu popup = new PopupMenu(sActivity, v); MenuInflater inflater = popup.getMenuInflater(); inflater.inflate(R.menu.my_popup_menu, popup.getMenu()); popup.show(); } }); } 

    De plus, votre problème pourrait être celui-ci: Numéro 152141

    J'espère que cela vous aidera, en respectant l'importation android.support.v7.widget.PopupMenu .

    Cordialement.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.