Reputation: 1391
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;
}
}
Upvotes: 1
Views: 2111
Reputation: 763
Hello dear you need to use this way in adapter
@Override
public void onBindViewHolder(@NonNull final RecentPlayedAdapter.MyViewHolder holder, final int position) {
holder.menudotes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PopupMenu popupMenu=new PopupMenu(context, holder.menudotes, Gravity.START);
popupMenu.getMenuInflater().inflate(R.menu.popupmenu1,popupMenu.getMenu());
popupMenu.show();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.download:
Toast.makeText(context, "Download", Toast.LENGTH_SHORT).show();
//Do position specific action with int position
break;
case R.id.playlist:
//Do position specific action with int position
Toast.makeText(context, "Playlist", Toast.LENGTH_SHORT).show();
break;
case R.id.share:
//Do position specific action with int position
Toast.makeText(context, "Share", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
});
}
});
}
Upvotes: 1
Reputation: 2077
Firstly, in the code snippet you've shown, it doesn't correlate with the available image.
Please provide your onBindViewHolder code. That is where the menu item's on click listener should be set.
Upvotes: 0
Reputation: 1391
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!
Upvotes: 2