web-dev-qa-db-fra.com

Android menu déroulant personnalisé

Comment créer un menu déroulant/contextuel personnalisé ancré à un bouton?

J'ai besoin que cela fonctionne comme le menu contextuel (ancré dans une vue) et que je fasse quelque chose lorsque je clique sur un élément du menu.

Comment ajouter des éléments au menu par code, en conservant la hauteur du menu et en le faisant défiler s'il y a plus de 5 éléments. Je n'ai pas besoin d'ajouter des images, juste du texte.

enter image description here

106
stanete

Pour créer un menu contextuel sous Android.

activity_main.xml

Il ne contient qu'un seul bouton.

Fichier: activity_main.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"  
    xmlns:tools="http://schemas.Android.com/tools"  
    Android:layout_width="match_parent"  
    Android:layout_height="match_parent"  
    Android:paddingBottom="@dimen/activity_vertical_margin"  
    Android:paddingLeft="@dimen/activity_horizontal_margin"  
    Android:paddingRight="@dimen/activity_horizontal_margin"  
    Android:paddingTop="@dimen/activity_vertical_margin"  
    tools:context=".MainActivity" >  

    <Button  
        Android:id="@+id/button1"  
        Android:layout_width="wrap_content"  
        Android:layout_height="wrap_content"  
        Android:layout_alignParentLeft="true"  
        Android:layout_alignParentTop="true"  
        Android:layout_marginLeft="62dp"  
        Android:layout_marginTop="50dp"  
        Android:text="Show Popup" />  

</RelativeLayout>  

popup_menu.xml

Il contient trois éléments comme indiqué ci-dessous. Il est créé dans le répertoire res/menu. Fichier: poupup_menu.xml

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android" >  

    <item  
        Android:id="@+id/one"  
        Android:title="One"/>  

    <item  
        Android:id="@+id/two"  
        Android:title="Two"/>  

    <item  
        Android:id="@+id/three"  
        Android:title="Three"/>  

</menu>  

Classe d'activité

Il affiche le menu contextuel en cliquant sur un bouton. Fichier: MainActivity.Java

public class MainActivity extends Activity {  
    private Button button1;  

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //Creating the instance of PopupMenu
                PopupMenu popup = new PopupMenu(MainActivity.this, button1);
                //Inflating the Popup using xml file
                popup.getMenuInflater()
                    .inflate(R.menu.popup_menu, popup.getMenu());

                //registering popup with OnMenuItemClickListener
                popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    public boolean onMenuItemClick(MenuItem item) {
                        Toast.makeText(
                            MainActivity.this,
                            "You Clicked : " + item.getTitle(),
                            Toast.LENGTH_SHORT
                        ).show();
                        return true;
                    }
                });

                popup.show(); //showing popup menu
            }
        }); //closing the setOnClickListener method
    }
}

Pour ajouter par programme:

PopupMenu menu = new PopupMenu(this, view);

menu.getMenu().add("One");
menu.getMenu().add("Two");
menu.getMenu().add("Three");

menu.show();

Suivez le lien this pour créer un menu par programme.

275
Shylendra Madda

Je sais que c’est une vieille question, mais j’ai trouvé une autre réponse qui a mieux fonctionné pour moi et qui ne semble apparaître dans aucune des réponses.

Créer une mise en page XML:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:paddingTop="5dip"
    Android:paddingBottom="5dip"
    Android:paddingStart="10dip"
    Android:paddingEnd="10dip">

<ImageView
    Android:id="@+id/shoe_select_icon"
    Android:layout_width="30dp"
    Android:layout_height="30dp"
    Android:layout_gravity="center_vertical"
    Android:scaleType="fitXY" />

<TextView
    Android:id="@+id/shoe_select_text"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_gravity="center"
    Android:textSize="20sp"
    Android:paddingStart="10dp"
    Android:paddingEnd="10dp"/>

</LinearLayout>

Créez une ListPopupWindow et une carte avec le contenu:

ListPopupWindow popupWindow;
List<HashMap<String, Object>> data = new ArrayList<>();
HashMap<String, Object> map = new HashMap<>();
    map.put(TITLE, getString(R.string.left));
    map.put(ICON, R.drawable.left);
    data.add(map);
    map = new HashMap<>();
    map.put(TITLE, getString(R.string.right));
    map.put(ICON, R.drawable.right);
    data.add(map);

Puis, au clic, affichez le menu en utilisant cette fonction:

private void showListMenu(final View anchor) {
    popupWindow = new ListPopupWindow(this);

    ListAdapter adapter = new SimpleAdapter(
            this,
            data,
            R.layout.shoe_select,
            new String[] {TITLE, ICON}, // These are just the keys that the data uses (constant strings)
            new int[] {R.id.shoe_select_text, R.id.shoe_select_icon}); // The view ids to map the data to

    popupWindow.setAnchorView(anchor);
    popupWindow.setAdapter(adapter);
    popupWindow.setWidth(400);
    popupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            switch (position){
                case 0:
                    devicesAdapter.setSelectedLeftPosition(devicesList.getChildAdapterPosition(anchor));
                    break;
                case 1:
                    devicesAdapter.setSelectedRightPosition(devicesList.getChildAdapterPosition(anchor));
                    break;
                default:
                    break;
            }
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    devicesAdapter.notifyDataSetChanged();
                }
            });
            popupWindow.dismiss();
        }
    });
    popupWindow.show();
}
6
Sir Codesalot

Commencez par créer un dossier nommé "menu" dans le dossier "res".

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android" >

    <item
        Android:id="@+id/search"
        Android:icon="@Android:drawable/ic_menu_search"
        Android:title="Search"/>
    <item
        Android:id="@+id/add"
        Android:icon="@Android:drawable/ic_menu_add"
        Android:title="Add"/>
    <item
        Android:id="@+id/edit"
        Android:icon="@Android:drawable/ic_menu_edit"
        Android:title="Edit">
        <menu>
            <item
                Android:id="@+id/share"
                Android:icon="@Android:drawable/ic_menu_share"
                Android:title="Share"/>
        </menu>
    </item>

</menu>

Ensuite, créez votre classe d’activité:

public class PopupMenu1 extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.popup_menu_1);
    }

    public void onPopupButtonClick(View button) {
        PopupMenu popup = new PopupMenu(this, button);
        popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu());

        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            public boolean onMenuItemClick(MenuItem item) {
                Toast.makeText(PopupMenu1.this,
                        "Clicked popup menu item " + item.getTitle(),
                        Toast.LENGTH_SHORT).show();
                return true;
            }
        });

        popup.show();
    }
}
3
sudhakara

La voie de Kotlin

fun showPopupMenu(view: View) {
    PopupMenu(view.context, view).apply {
                menuInflater.inflate(R.menu.popup_men, menu)
                setOnMenuItemClickListener { item ->
                    Toast.makeText(view.context, "You Clicked : " + item.title, Toast.LENGTH_SHORT).show()
                    true
                }
            }.show()
}

PDATE: Dans le code ci-dessus, la fonction apply renvoie this, ce qui n'est pas obligatoire, afin que nous puissions utiliser run qui ne renvoie rien et pour le rendre encore plus simple peut également supprimer les accolades de la méthode showPopupMenu.

Encore plus simple:

fun showPopupMenu(view: View) = PopupMenu(view.context, view).run {
            menuInflater.inflate(R.menu.popup_men, menu)
            setOnMenuItemClickListener { item ->
                Toast.makeText(view.context, "You Clicked : ${item.title}", Toast.LENGTH_SHORT).show()
                true
            }
            show()
        }
3
Sai Kiran