Bin*_*abu 89 android contextmenu android-recyclerview
如何实现上下文菜单RecyclerView?显然调用registerForContextMenu(recyclerView)不起作用.我是从片段中调用它的.有没有人有成功实现这个?
小智 90
感谢您的信息和评论.我能够实现ContextMenu物品Recyclerview.
这就是我做的
在Fragment的onViewCreated方法或Activity的onCreate方法中:
registerForContextMenu(mRecyclerView);
Run Code Online (Sandbox Code Playgroud)
然后在Adapter add中
private int position;
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
Run Code Online (Sandbox Code Playgroud)
使ViewHolder类实现OnCreateContextMenuListener
public static class ViewHolder extends RecyclerView.ViewHolder
implements View.OnCreateContextMenuListener {
public ImageView icon;
public TextView fileName;
public ImageButton menuButton;
public ViewHolder(View v) {
super(v);
icon = (ImageView)v.findViewById(R.id.file_icon);
fileName = (TextView)v.findViewById(R.id.file_name);
menuButton = (ImageButton)v.findViewById(R.id.menu_button);
v.setOnCreateContextMenuListener(this);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
//menuInfo is null
menu.add(Menu.NONE, R.id.ctx_menu_remove_backup,
Menu.NONE, R.string.remove_backup);
menu.add(Menu.NONE, R.id.ctx_menu_restore_backup,
Menu.NONE, R.string.restore_backup);
}
}
Run Code Online (Sandbox Code Playgroud)
onBindViewHolder方法添加OnLongClickListener在holder.itemView上以捕获加载上下文菜单之前的位置:
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
setPosition(holder.getPosition());
return false;
}
});
Run Code Online (Sandbox Code Playgroud)
然后onViewRecycled删除监听器,以便没有引用问题.(可能不是必需的).
@Override
public void onViewRecycled(ViewHolder holder) {
holder.itemView.setOnLongClickListener(null);
super.onViewRecycled(holder);
}
Run Code Online (Sandbox Code Playgroud)
最后在Fragment/Activity中覆盖onContextItemSelected如下:
@Override
public boolean onContextItemSelected(MenuItem item) {
int position = -1;
try {
position = ((BackupRestoreListAdapter)getAdapter()).getPosition();
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage(), e);
return super.onContextItemSelected(item);
}
switch (item.getItemId()) {
case R.id.ctx_menu_remove_backup:
// do your stuff
break;
case R.id.ctx_menu_restore_backup:
// do your stuff
break;
}
return super.onContextItemSelected(item);
}
Run Code Online (Sandbox Code Playgroud)
Pra*_*kar 85
你不能直接实现这样的方法onClickListener, OnContextMenuListener因为等RecycleView延伸android.view.ViewGroup.所以我们不能直接使用这些方法.我们可以在ViewHolder适配器类中实现这些方法.我们可以像这样使用RecycleView中的上下文菜单:
public static class ViewHolder extends RecyclerView.ViewHolder implements OnCreateContextMenuListener {
TextView tvTitle;
ImageView ivImage;
public ViewHolder(View v) {
super(v);
tvTitle =(TextView)v.findViewById(R.id.item_title);
v.setOnCreateContextMenuListener(this);
}
Run Code Online (Sandbox Code Playgroud)
现在我们在实现上下文菜单时遵循相同的过程.
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Select The Action");
menu.add(0, v.getId(), 0, "Call");//groupId, itemId, order, title
menu.add(0, v.getId(), 0, "SMS");
}
Run Code Online (Sandbox Code Playgroud)
如果您遇到任何困难,请在评论中提问.
Ren*_*ato 26
目前的答案是不正确的.这是一个有效的实现:
public class ContextMenuRecyclerView extends RecyclerView {
private RecyclerViewContextMenuInfo mContextMenuInfo;
@Override
protected ContextMenu.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 = new RecyclerViewContextMenuInfo(longPressPosition, longPressId);
return super.showContextMenuForChild(originalView);
}
return false;
}
public static class RecyclerViewContextMenuInfo implements ContextMenu.ContextMenuInfo {
public RecyclerViewContextMenuInfo(int position, long id) {
this.position = position;
this.id = id;
}
final public int position;
final public long id;
}
}
Run Code Online (Sandbox Code Playgroud)
在你的片段(或活动)中:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView = view.findViewById(R.id.recyclerview);
registerForContextMenu(mRecyclerView);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// inflate menu
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.my_context_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
return super.onContextItemSelected(item);
RecyclerViewContextMenuInfo info = (RecyclerViewContextMenuInfo) item.getMenuInfo();
// handle menu item here
}
Run Code Online (Sandbox Code Playgroud)
最后,在您的ViewHolder中:
class MyViewHolder extends RecyclerView.View.ViewHolder {
...
private void onLongClick() {
itemView.showContextMenu();
}
}
Run Code Online (Sandbox Code Playgroud)
小智 21
尝试View使用recycleView中的项目
.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.add("delete").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
//do what u want
return true;
}
});
}
});
Run Code Online (Sandbox Code Playgroud)
您可以将其用于将数据设置为ViewHolder项目
Val*_*kov 15
Prabhakar 答案是正确的,但他没有解释如何在选择上下文菜单项时获取与按下的项目相关的数据.我们可以使用onContextItemSelected回调,但在这种情况下ContextMenuInfo不可用(null)如果getContextMenuInfo()按下的视图没有覆盖方法.所以,最简单的解决方案是OnMenuItemClickListener直接添加到MenuItem.
private class ViewHolder extends RecyclerView.ViewHolder {
private final TextView mTitleTextView;
private MyItemData mData;
public ViewHolder(View view) {
super(view);
mTitleTextView = (TextView)view.findViewById(R.id.title);
view.setOnCreateContextMenuListener(mOnCreateContextMenuListener);
}
public void bind(@NonNull MyItemData data) {
mData = data;
String title = mData.getTitle();
mTitleTextView.setText(title);
}
private final View.OnCreateContextMenuListener mOnCreateContextMenuListener = new View.OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
if (mData!= null) {
MenuItem myActionItem = menu.add("My Context Action");
myActionItem.setOnMenuItemClickListener(mOnMyActionClickListener);
}
}
};
private final MenuItem.OnMenuItemClickListener mOnMyActionClickListener = new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
//todo: process item click, mData is available here!!!
return true;
}
};
}
Run Code Online (Sandbox Code Playgroud)
jos*_*112 11
@ Renaud的回答对我有用,但首先需要几个代码修复.这就像他从代码的几个不同迭代中发布了片段.需要做出的改变是:
RecyclerContextMenuInfo并且RecyclerViewContextMenuInfo是同一个班级.选择一个名字并坚持下去.ViewHolder必须执行View.OnLongClickListener,并记住调用setOnLongClickListener()构造函数内的项目.onLongClick()听众中,getView().showContextMenu()是完全错误的.你必须打电话给showContextMenuForChild()你ContextMenuRecyclerView,否则ContextMenuInfo你进去onCreateContextMenu(),onContextItemSelected()将是空的.我编辑的代码如下:
ContextMenuRecyclerView:
public class ContextMenuRecyclerView extends RecyclerView {
private RecyclerViewContextMenuInfo mContextMenuInfo;
@Override
protected ContextMenu.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 = new RecyclerViewContextMenuInfo(longPressPosition, longPressId);
return super.showContextMenuForChild(originalView);
}
return false;
}
public static class RecyclerViewContextMenuInfo implements ContextMenu.ContextMenuInfo {
public RecyclerViewContextMenuInfo(int position, long id) {
this.position = position;
this.id = id;
}
final public int position;
final public long id;
}
}
Run Code Online (Sandbox Code Playgroud)
在你的片段中:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView = view.findViewById(R.id.recyclerview);
registerForContextMenu(mRecyclerView);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// inflate menu here
// If you want the position of the item for which we're creating the context menu (perhaps to add a header or something):
int itemIndex = ((ContextMenuRecyclerView.RecyclerViewContextMenuInfo) menuInfo).position;
}
@Override
public boolean onContextItemSelected(MenuItem item) {
ContextMenuRecyclerView.RecyclerViewContextMenuInfo info = (ContextMenuRecyclerView.RecyclerViewContextMenuInfo) item.getMenuInfo();
// handle menu here - get item index or ID from info
return super.onContextItemSelected(item);
}
Run Code Online (Sandbox Code Playgroud)
在您的ViewHolder中:
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener {
public MyViewHolder( View itemView ) {
super( itemView );
itemView.setOnLongClickListener( this );
}
@Override public boolean onLongClick() {
recyclerView.showContextMenuForChild( v );
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
此外,请确保您更换RecyclerView同ContextMenuRecyclerView在布局!
Moh*_*adL 11
在适配器类中:
/**
* Custom on long click item listener.
*/
onLongItemClickListener mOnLongItemClickListener;
public void setOnLongItemClickListener(onLongItemClickListener onLongItemClickListener) {
mOnLongItemClickListener = onLongItemClickListener;
}
public interface onLongItemClickListener {
void ItemLongClicked(View v, int position);
}
Run Code Online (Sandbox Code Playgroud)
在onBindViewHolder挂钩自定义侦听器中:
// Hook our custom on long click item listener to the item view.
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (mOnLongItemClickListener != null) {
mOnLongItemClickListener.ItemLongClicked(v, position);
}
return true;
}
});
Run Code Online (Sandbox Code Playgroud)
在 MainActivity (Activity/Fragment) 中创建一个字段:
private int mCurrentItemPosition;
Run Code Online (Sandbox Code Playgroud)
在您的 Adapter 对象中设置自定义侦听器:
mAdapter.setOnLongItemClickListener(new FileAdapter.onLongItemClickListener() {
@Override
public void ItemLongClicked(View v, int position) {
mCurrentItemPosition = position;
}
});
Run Code Online (Sandbox Code Playgroud)
现在,您长按的任何项目都有一个美味的位置
在 res -> menu
创建一个包含你的菜单项的文件context_menu_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/delete" android:title="Delete"/>
<item android:id="@+id/share" android:title="Share"/>
</menu>
Run Code Online (Sandbox Code Playgroud)
在 MainActivity 中:同时
实现onCreateContextMenu和onContextItemSelected:
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu_main, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.delete) {
}
if (id == R.id.share) {
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
显示上下文菜单。
registerForContextMenu(mRecyclerView);
mAdapter.setOnLongItemClickListener(new FileAdapter.onLongItemClickListener() {
@Override
public void ItemLongClicked(View v, int position) {
mCurrentItemPosition = position;
v.showContextMenu();
}
});
Run Code Online (Sandbox Code Playgroud)希望我不会忘记任何事情
菜单文档中的更多信息
小智 9
这是使用 Kotlin 的一种更简单的方法,它对我有用。主要的挑战是弄清楚被按下的项目的位置。在您的适配器中,您可以放置此代码片段,它将能够捕获显示上下文菜单的项目的位置;就这样。
override fun onBindViewHolder(holder: YourViewHolder, position: Int) {
...
holder.view.setOnCreateContextMenuListener { contextMenu, _, _ ->
contextMenu.add("Add").setOnMenuItemClickListener {
longToast("I'm pressed for the item at position => $position")
true
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
68179 次 |
| 最近记录: |