I want to realize a custom popup menu like Twitter in Android for example with item and picture but I don't know what's the component used for that.
In Material Design website, google present this solution. So I think, there is a native solution to achieve this.
I tried with Popup menu, but I can't find how to customize the layout of this view like that.
Go to app > res > menu > right-click > New > Menu Resource File and create a menu resource file and name it as popup_menu. In the popup_menu file, we will add menu items. Below is the code snippet for the popup_menu. xml file.
A PopupMenu displays a Menu in a modal popup window anchored to a View . The popup will appear below the anchor view if there is room, or above it if there is not. If the IME is visible the popup will not overlap it until it is touched.
There are three types of menus in Android: Popup, Contextual and Options. Each one has a specific use case and code that goes along with it.
Android Popup Menu displays a list of items in a vertical list which presents the view that invoked the menu and is useful to provide an overflow of actions related to specific content.
you can use a ListPopupWindow, submitting your custom adapter, through which you can control the layout of every single row of the ListPopupWindow
. As for a normal PopupWindow
you have to provide an anchor view and additionally you have to call setContentWidth
on the instance of ListPopupWindow
, which sets the width of the popup window by the size of its content. It is a small price you have to pay, but for a small dataset is not a big deal. I have this utility method to retrieve the max width of the row:
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; }
There's a widget called PopupMenu
which is basically a menu anchored to a specific view. One drawback is that it doesn't display icons by default.
However, you can use reflection and call setForceShowIcon
to reveal them. The code that you need is:
Since a PopupMenu
is anchored to a specific view, your ActionBar
item has an actionLayout
attribute. That layout (action_item.xml
) can be as simple as:
<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
menu style that contains your item with the above layout
<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>
Your popup_menu.xml
, the layout you'll inflate for your 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>
And finally code to perform the inflation when an ActionBar
item is clicked
@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);
}
Note, that to get that multi-line text in a menu, you'd need to use an actionLayout
for your popup menu items too.
Use a Pop-Up list fragment. The nice thing about fragments is that you can easily animate them (If you don't understand fragments I recommend first reading Fragment Introduction)
If you want complete control over the pop-up content then see Dialog Fragment
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With