Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create Options Menu for RecyclerView-Item

How do I create an Options Menu like in the following Screenshot:

enter image description here

The Options Menu should be opened afther clicking on the "More"-Icon of a RecyclerView Item!

My try was this:

@Override public void onBindViewHolder(Holder holder, int position) {     holder.txvSongTitle.setText(sSongs[position].getTitle());     holder.txvSongInfo.setText(sSongs[position].getAlbum() + " - " + sSongs[position].getArtist());  holder.btnMore.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             Toast.makeText(mContext, "More...", Toast.LENGTH_SHORT).show();         }     }); } 

But this causes problems because the full item is clicked if I touch on the RecyclerView Item More-Button...

Here's my RecyclerViewOnTouchListener:

public class RecyclerViewOnTouchListener implements RecyclerView.OnItemTouchListener {     private GestureDetector mGestureDetector;     private OnTouchCallback mOnTouchCallback;      public RecyclerViewOnTouchListener(Context context, final RecyclerView recyclerView, final OnTouchCallback onTouchCallback) {         mOnTouchCallback = onTouchCallback;          mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {             @Override             public boolean onSingleTapUp(MotionEvent e) {                 return true;             }              @Override             public void onLongPress(MotionEvent e) {                 View child = recyclerView.findChildViewUnder(e.getX(), e.getY());                  if (child != null && onTouchCallback != null) {                     onTouchCallback.onLongClick(child, recyclerView.getChildLayoutPosition(child));                 }                  super.onLongPress(e);             }         });     }      @Override     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {         View child = rv.findChildViewUnder(e.getX(), e.getY());          if (child != null && mOnTouchCallback != null && mGestureDetector.onTouchEvent(e)) {             mOnTouchCallback.onClick(child, rv.getChildLayoutPosition(child));         }          return false;     }      @Override     public void onTouchEvent(RecyclerView rv, MotionEvent e) {      }      @Override     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {      }      public interface OnTouchCallback {         void onClick(View view, int position);         void onLongClick(View view, int position);     } } 

I wasn't able to find any similar problem so I hope you can help me!

like image 250
the_dani Avatar asked Jun 02 '16 20:06

the_dani


People also ask

How to Create popup menu in RecyclerView android?

OnClickListener() { @Override public void onClick(View view) { //creating a popup menu PopupMenu popup = new PopupMenu(mCtx, holder. buttonViewOption); //inflating menu from xml resource popup. inflate(R. menu.

How can I access any component outside RecyclerView from RecyclerView in Android?

The best way to do this is via a click listener which will allow you to set up a communication between your RecyclerView items and the widgets or views outside of the recycler View. And that's all.


2 Answers

It is very easy to create an option menu like this. Just add a button in your list item design. You can use the following string to display 3 vertical dots.

<TextView     android:id="@+id/textViewOptions"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_alignParentRight="true"     android:layout_alignParentTop="true"     android:paddingLeft="@dimen/activity_horizontal_margin"     android:text="&#8942;"     android:textAppearance="?android:textAppearanceLarge" /> 

Now in your adapter inside onBindViewHolder() use the following code.

holder.buttonViewOption.setOnClickListener(new View.OnClickListener() {     @Override     public void onClick(View view) {          //creating a popup menu         PopupMenu popup = new PopupMenu(mCtx, holder.buttonViewOption);         //inflating menu from xml resource         popup.inflate(R.menu.options_menu);         //adding click listener         popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {             @Override             public boolean onMenuItemClick(MenuItem item) {                 switch (item.getItemId()) {                     case R.id.menu1:                         //handle menu1 click                         return true;                     case R.id.menu2:                         //handle menu2 click                         return true;                     case R.id.menu3:                         //handle menu3 click                         return true;                     default:                         return false;                 }             }         });         //displaying the popup         popup.show();      } }); 

Thats it.

Source: Options Menu For RecyclerView Item

like image 198
Shaba Aafreen Avatar answered Sep 21 '22 14:09

Shaba Aafreen


I found out that the only Menu, that looks like the Menu above is the PopupMenu.

So in onClick:

@Override public void onClick(View view, int position, MotionEvent e) {     ImageButton btnMore = (ImageButton) view.findViewById(R.id.item_song_btnMore);      if (RecyclerViewOnTouchListener.isViewClicked(btnMore, e)) {         PopupMenu popupMenu = new PopupMenu(view.getContext(), btnMore);          getActivity().getMenuInflater().inflate(R.menu.menu_song, popupMenu.getMenu());          popupMenu.show();          //The following is only needed if you want to force a horizontal offset like margin_right to the PopupMenu         try {             Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");             fMenuHelper.setAccessible(true);             Object oMenuHelper = fMenuHelper.get(popupMenu);              Class[] argTypes = new Class[] {int.class};              Field fListPopup = oMenuHelper.getClass().getDeclaredField("mPopup");             fListPopup.setAccessible(true);             Object oListPopup = fListPopup.get(oMenuHelper);             Class clListPopup = oListPopup.getClass();              int iWidth = (int) clListPopup.getDeclaredMethod("getWidth").invoke(oListPopup);              clListPopup.getDeclaredMethod("setHorizontalOffset", argTypes).invoke(oListPopup, -iWidth);              clListPopup.getDeclaredMethod("show").invoke(oListPopup);         }         catch (NoSuchFieldException nsfe) {             nsfe.printStackTrace();         }         catch (NoSuchMethodException nsme) {             nsme.printStackTrace();         }         catch (InvocationTargetException ite) {             ite.printStackTrace();         }         catch (IllegalAccessException iae) {             iae.printStackTrace();         }     }     else {         MusicPlayer.playSong(position);     } } 

You have to make your onClick-Method pass the MotionEvent and finally implement the Method isViewClicked in your RecyclerViewOnTouchListener:

public static boolean isViewClicked(View view, MotionEvent e) {     Rect rect = new Rect();      view.getGlobalVisibleRect(rect);      return rect.contains((int) e.getRawX(), (int) e.getRawY()); } 
like image 22
the_dani Avatar answered Sep 20 '22 14:09

the_dani