Android custom dropdown/popup menu
Solution 1
Update: To create a popup menu in android with Kotlin refer my answer here.
To create a popup menu in android with Java:
Create a layout file activity_main.xml
under res/layout
directory which contains only one button.
Filename: 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>
Create a file popup_menu.xml
under res/menu
directory
It contains three items as shown below.
Filename: 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 class which displays the popup menu on button click.
Filename: 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
}
}
To add programmatically:
PopupMenu menu = new PopupMenu(this, view);
menu.getMenu().add("One");
menu.getMenu().add("Two");
menu.getMenu().add("Three");
menu.show();
Follow this link for creating menu programmatically.
Solution 2
I know this is an old question, but I've found another answer that worked better for me and it doesn't seem to appear in any of the answers.
Create a layout 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>
Create a ListPopupWindow and a map with the content:
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);
Then on click, display the menu using this function:
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();
}
Solution 3
The Kotlin Way
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()
}
UPDATE: In the above code, the apply function returns this
which is not required, so we can use run
which don't return anything and to make it even simpler we can also remove the curly braces of showPopupMenu method.
Even Simpler:
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()
}
Solution 4
First, create a folder named “menu” in the “res” folder.
<?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>
Then, create your Activity Class:
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();
}
}
Comments
-
stanete about 4 years
How do I do a custom dropdown/popup menu anchored to a button?
I need it to work like the popup menu (anchored to a view), and do something when I click an item from the menu.
How do I add items to the menu by code, keeping menu's height and make it scrollable if there are more than 5 items. I don't need to add any images, just text.
-
stanete over 10 yearsHey thank you!! What if I want to add more items to the menu?. Can I do that by code?
-
Shailendra Madda over 10 yearswelcome.. yes you can add more items in popup_menu.xml
-
stanete over 10 yearsBut how can I do it in my main class? How can I add items via java?
-
stanete over 10 yearsOk I found out how to add items: menu.getMenu().add("item"); But how can I customize the menu?
-
Shailendra Madda over 10 yearsyou can customize it like by using
popup.getMenu().add(groupId, itemId, order, title);
-
stanete over 10 yearsI mean the width, the background, etc.
-
Shailendra Madda over 10 yearsOnce refer this it may helps you stackoverflow.com/questions/4591164/…
-
Bahadır Yıldırım over 10 years@DavidStanete If this provides a solution to your question, don't forget to mark this answer as accepted. If you have any follow-up questions, feel free to ask a new question and provide a link.
-
AndroidMech almost 10 yearsNow it can also be used in lower versions ie below 3.0(honeycomb) by using the v7 compat support library..
-
Shailendra Madda almost 10 years@Mr.G Yes, You can add icon too by adding this line in popup_menu.xml
android:icon="@drawable/ic_action_camera"
in every menu item -
Mr.G almost 10 years<item android:id="@+id/google_plus" android:title="@string/menu_google_plus" android:icon="@drawable/add_by_gp" android:showAsAction="ifRoom|withText" /> this is how i added , but i cant see image with text
-
Shailendra Madda almost 10 yearsReplace this
android:showAsAction="ifRoom|withText"
withapp:showAsAction="always|withText"
-
Mr.G almost 10 yearsi replaced with app:showAsAction="always|withText" , but it gives me an error, i put android:showAsAction="always|withText", but it didnt give me an image
-
Shailendra Madda almost 10 yearsis there an image
add_by_gp
in drawable folder?? -
Mr.G almost 10 yearsLet us continue this discussion in chat.
-
Ankur1994a over 8 years@ShylendraMadda Heyy thanks, this is really needfull.
-
Shailendra Madda over 7 yearsGlad to helped you.. @anuragshrivastava
-
Shailendra Madda over 7 years@FloWe for that you might look this stackoverflow.com/questions/27782846/…
-
Flo We over 7 years@ShylendraMadda thanks, but i meant setting a custom adapter for the Popup to display items instead of XML Menues.
-
Shailendra Madda over 5 years@FloWe It should be a new question