【问题标题】:Android custom dropdown/popup menuAndroid自定义下拉/弹出菜单
【发布时间】:2014-02-15 05:43:01
【问题描述】:

如何将自定义下拉/弹出菜单锚定到按钮?

我需要它像弹出菜单(锚定到视图)一样工作,并在我单击菜单中的项目时执行某些操作。

如何通过代码将项目添加到菜单中,保持菜单的高度并在超过 5 个项目时使其可滚动。我不需要添加任何图像,只需添加文本。

【问题讨论】:

    标签: android drop-down-menu menu android-menu popupmenu


    【解决方案1】:

    更新:要使用 Kotlin 在 android 中创建弹出菜单,请参阅我的回答 here

    使用 Java 在 android 中创建弹出菜单:

    res/layout目录下创建一个布局文件activity_main.xml,只包含一个按钮。

    文件名: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>  
    

    res/menu目录下创建文件popup_menu.xml

    它包含三个项目,如下所示。

    文件名: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>  
    

    MainActivity 类,在单击按钮时显示弹出菜单。

    文件名: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
        }
    }
    

    以编程方式添加:

    PopupMenu menu = new PopupMenu(this, view);
    
    menu.getMenu().add("One");
    menu.getMenu().add("Two");
    menu.getMenu().add("Three");
    
    menu.show();
    

    按照this 链接以编程方式创建菜单。

    【讨论】:

    • 嘿,谢谢!如果我想在菜单中添加更多项目怎么办?我可以通过代码做到这一点吗?
    • 好的,我知道了如何添加项目:menu.getMenu().add("item");但是如何自定义菜单呢?
    • 我指的是宽度、背景等
    • 现在它也可以通过使用 v7 兼容支持库在较低版本中使用,即低于 3.0(honeycomb)..
    • 这就是我添加的方式,但我看不到带文字的图像
    【解决方案2】:

    我知道这是一个老问题,但我找到了另一个更适合我的答案,而且似乎没有出现在任何答案中。

    创建布局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>
    

    创建一个 ListPopupWindow 和一个包含内容的地图:

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

    然后在点击时,使用此功能显示菜单:

    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();
    }
    

    【讨论】:

      【解决方案3】:

      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()
      }
      

      更新: 在上面的代码中,apply 函数返回this,这不是必需的,所以我们可以使用不返回任何内容的run,为了更简单,我们可以同时删除 showPopupMenu 方法的花括号。

      更简单:

      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()
              }
      

      【讨论】:

        【解决方案4】:

        首先,在“res”文件夹中创建一个名为“menu”的文件夹。

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

        然后,创建您的 Activity 类:

        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();
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2011-02-28
          • 1970-01-01
          • 2015-07-15
          • 2020-05-11
          • 2012-10-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多