Skip to content

Instantly share code, notes, and snippets.

@FrancoisBlavoet
Last active October 26, 2016 23:38
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FrancoisBlavoet/cba0aa150e60b727636d to your computer and use it in GitHub Desktop.
Save FrancoisBlavoet/cba0aa150e60b727636d to your computer and use it in GitHub Desktop.
ContextMenuRecyclerView - simple sample on how to adapt an existing ContextMenu to RecyclerView
import android.content.Context;
import android.util.AttributeSet;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View;
public class ContextMenuRecyclerView extends RecyclerView {
public ContextMenuRecyclerView(Context context) {
super(context);
}
public ContextMenuRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ContextMenuRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private ContextMenuInfo mContextMenuInfo = null;
@Override
protected ContextMenuInfo getContextMenuInfo() {
return mContextMenuInfo;
}
@Override
public boolean showContextMenuForChild(View originalView) {
final int longPressPosition = getChildPosition(originalView);
if (longPressPosition >= 0) {
final long longPressId = getAdapter().getItemId(longPressPosition);
mContextMenuInfo = createContextMenuInfo(longPressPosition, longPressId);
return super.showContextMenuForChild(originalView);
}
return false;
}
ContextMenuInfo createContextMenuInfo(int position, long id) {
return new RecyclerContextMenuInfo(position, id);
}
/**
* Extra menu information provided to the
* {@link android.view.View.OnCreateContextMenuListener#onCreateContextMenu(android.view.ContextMenu, View, ContextMenuInfo) }
* callback when a context menu is brought up for this AdapterView.
*/
public static class RecyclerContextMenuInfo implements ContextMenu.ContextMenuInfo {
public RecyclerContextMenuInfo(int position, long id) {
this.position = position;
this.id = id;
}
/**
* The position in the adapter for which the context menu is being
* displayed.
*/
public int position;
/**
* The row id of the item for which the context menu is being displayed.
*/
public long id;
}
}
ContextMenuRecyclerView extends Recycler View {
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//...
registerForContextMenu(mList);
}
//////////////////////////////////////////////////////////////////
//// Menu
//////////////////////////////////////////////////////////////////
@Override
public void onContextualMenuClicked(Track track, View view) {
//call this callback from your viewholder.
getActivity().openContextMenu(view);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
dz.ui.Menu.MenuItem[] currentContextMenuItems = getCurrentContextMenuItems(
menu, v, menuInfo);
if (currentContextMenuItems != null) {
View header = View.inflate(getActivity(),
R.layout.context_menu_header, null);
menu.setHeaderView(header);
// configure the header and add your menuItems
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
// Never call super.onOptionsItemSelected(item), otherwise there will be a infinite loop
ABaseActivity activity = (ABaseActivity) getActivity();
return activity.onMenuEvent(activity,
dz.ui.Menu.getSavedMenuItem(item.getItemId()));
}
public void customizeContextMenuHeaderView(ContextMenu.ContextMenuInfo menuInfo, RemoteImageView picture,
TextView mainText, TextView secondText, TextView thirdTextView) {
ContextMenuRecyclerView.RecyclerContextMenuInfo info =
(ContextMenuRecyclerView.RecyclerContextMenuInfo) menuInfo;
if (mAdapter == null) {
return;
}
int position = info.position;
mAdapter.getItem(position);
// customize the headerView according to the corresponding item in the adapter (not mandatory)
}
public Menu.MenuItem[] getCurrentContextMenuItems(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
if (mAdapter == null) {
return null;
}
RecyclerContextMenuInfo info =
(ContextMenuRecyclerView.RecyclerContextMenuInfo) menuInfo;
int position = info.position;
///// do whatever you need to get your MenuItem Array and return it.
return null;
}
}
@FrancoisBlavoet
Copy link
Author

I wrote this for the RecyclerView preview code, there might be an easier/cleaner way to do this now.

@SrMouraSilva
Copy link

hello! could suggest how I could do:

ContextMenuRecyclerView view = (ContextMenuRecyclerView) activity.findViewById(id);

would have to turn ContextMenuRecyclerView in a Adapter?

I'm try

    <ContextMenuRecyclerView
        android:id="@+id/repertorios_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

but...

```JAVA
android.view.InflateException: Binary XML file line #48: Error inflating class ContextMenuRecyclerView

@vladskiy
Copy link

Use fully qualified name instead of just ContextMenuRecyclerView.

@diceroll123
Copy link

Hey, I needed to get the targetView of the ContextMenuInfo, and it works if you just add support for a View targetView in RecyclerContextMenuInfo

public static class RecyclerContextMenuInfo implements ContextMenu.ContextMenuInfo {

    public RecyclerContextMenuInfo(int position, long id, View targetView) {
        this.position = position;
        this.id = id;
        this.targetView = targetView;
    }

    public int position;
    public long id;
    public View targetView;
}

So you can access the context menu title. 👍

(For anyone who may need it...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment