Using a RecylcerView
, I'm trying to have a popup menu for each item in the list, similar to this:
Creating the popup menu is simple, but how do you get the position of the item clicked in onMenuItemClicked
?
public class Activity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
public void showPopupMenu(View v) {
PopupMenu popupMenu = new PopupMenu(this, v);
MenuInflater inflater = popupMenu.getMenuInflater();
inflater.inflate(R.menu.edit_delete_menu, popupMenu.getMenu());
popupMenu.show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
//get position here from RecyclerView here?
switch (item.getItemId()) {
case R.id.edit:
//Do position specific action
break;
case R.id.delete:
//Do position specific action
break;
}
return false;
}
}
Alright, so I (surprisingly) managed to answer my own question here.
In order to obtain the position from a RecylcerView
adapter within onMenuItemClicked
using PopupMenu
, I created a custom implementation of PopupMenu
.
Doing so provides much greater flexibility when using PopupMenu
, such as displaying icons in your menus.
Look at Google's source code for PopupMenu
, and create your own, something like MyPopupMenu
that is exactly the same, but you can modify certain instances of what the class can do.
To complete my problem, I added an OnClickListener
to the More button within my RecyclerView.Adapter
. When clicked, the button calls an interface method that passes both the button view, and the adapter's current position.
In the custom implementation of MyPopupMenu
, add the variable requirements for each constructor for an int value. Also add int position
to the interface method onMenuItemClick(MenuItem item, int position)
within MyPopupMenu
.
Finally, assemble in the activity class.
public class MyActivity extends AppCompatActivity implements MyAdapter.OnItemEventListener, PopupMenu.OnMenuItemClickListener {
@Override
public void onMoreClicked(View v, int position) {
MyPopupMenu popupMenu = new MyPopupMenu(this, v, position);
MenuInflater inflater = popupMenu.getMenuInflater();
inflater.inflate(R.menu.edit_delete_menu, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(this);
popupMenu.show();
}
@Override
public boolean onMenuItemClick(MenuItem item, int position) {
switch (item.getItemId()) {
case R.id.edit:
//Do position specific action with int position
break;
case R.id.delete:
//Do position specific action with int position
break;
}
return false;
}
}
class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private final OnItemEventListener onItemEventListener;
static class ViewHolder extends RecyclerView.ViewHolder {
ImageButton more;
ViewHolder(View v) {
super(v);
more = (ImageButton) v.findViewById(R.id.list_item_more_button);
}
}
public NewGameAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
final ViewHolder viewHolder = new ViewHolder(v);
viewHolder.more.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onItemEventListener.onMoreClicked(viewHolder.more, viewHolder.getAdapterPosition());
}
});
return viewHolder;
}
interface OnItemEventListener {
void onMoreClicked(View v, int position);
}
}
Let me know what you guys think!