AdapterView.AdapterContextMenuInfo 为空
AdapterView.AdapterContextMenuInfo is null
这是我的问题,我的架构是 class :
- Activity
- 片段
- RecyclerView(有适配器)
适配器:
有一个 class ViewHolder:
public static class NoteViewHolder extends RecyclerView.ViewHolder
implements View.OnCreateContextMenuListener{
TextView noteName;
public NoteViewHolder(View itemView) {
super(itemView);
noteName = (TextView)itemView.findViewById(R.id.note_name);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {/**/}
});
itemView.setOnCreateContextMenuListener(this);
}
@Override
public void onCreateContextMenu(ContextMenu contextMenu, View view,
ContextMenu.ContextMenuInfo contextMenuInfo) {
contextMenu.setHeaderTitle("Select The Action");
contextMenu.add(0,666,0,"Delete Note");
}
}
片段
overrrides onContextItemSelected(MenuItem item){
//info is null
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
}
它还调用
registerForContextMenu(recyclerView);
顺序
- 我长按 NoteViewHolder,它会打开上下文菜单
- 我select"Delete"
- 使用 contextMenuInfo == null 调用 OnCreateContextMenu
- onSelectedContextItem 使用 item.getMenuInfo() == null
调用
如何获取非空的 menuInfo?
我应该自己创建菜单信息吗?如果是,在哪里?
PS,我看过这个post:How to create context menu for RecyclerView,我没有看到这个
的答案
PS2 我也读过这个:http://androidheight.blogspot.fr/2015/03/recyclerview-widget-example-in-android.html,对我来说 new RecyclerAdapter().info = menuInfo;
这行似乎是错误的
谢谢
您需要在 RecyclerView 的 activity 中调用 registerForContextMenu()
。
这是一个我认为足够干净并为此实施的解决方案。
在适配器中,我创建了一个要实现的接口(由另一个 class,例如 activity 或我的片段)。
我将接口实现传递给适配器的CTOR。它可以以不同的方式传递,这只是这里的一个选择,因为我在片段或 activity 中创建了适配器,所以无论如何我都可以立即传递接口实现。
这个接口可以有你想要的方法。
public interface NoteListCommandListener{
void updateList();
void remove(Note n);
}
RVNoteAdapter(NoteListCommandListener noteListCommandListener){
super();
mNoteListCommandListener = noteListCommandListener;
}
我修改了 onBindViewHolder 方法,将接口实现从适配器传递给每个视图持有者。
@Override
public void onBindViewHolder(NoteViewHolder personViewHolder, int i) {
String name = notes.get(i).name;
personViewHolder.noteName.setText(name);
personViewHolder.noteListCommandListener= mNoteListCommandListener;
}
然后在视图持有者 CTOR 中,我使用 setOnCreateContextMenuListener,我在本地指定 class 因为当我调用 setOnMenuItemClickListener 时我仍然可以访问 noteListCommandListener 并且我可以直接调用它的任何函数。
public static class NoteViewHolder extends RecyclerView.ViewHolder
{
TextView noteName;
NoteListCommandListener noteListCommandListener;
public NoteViewHolder(View itemView) {
super(itemView);
noteName = (TextView)itemView.findViewById(R.id.note_name);
itemView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
contextMenu.setHeaderTitle("Select The Action");
contextMenu.add(0,42,0,"Delete Note").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
noteListCommandListener.remove(n);
return true;
}
});
}
});
}
}
优点是view holder的整个上下文菜单都在view holder中编码,很简单。
如果您需要动态更改上下文菜单(不是我的情况),则它的缺点是不能很好地分离。如果这样做,您可以避免在本地定义 2 class 并通过在 CTORS 中传递适当的参数来传递 class 在该范围之外定义。
谢谢大家的指教
这是我的问题,我的架构是 class :
- Activity
- 片段
- RecyclerView(有适配器)
- 片段
适配器:
有一个 class ViewHolder:
public static class NoteViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener{ TextView noteName; public NoteViewHolder(View itemView) { super(itemView); noteName = (TextView)itemView.findViewById(R.id.note_name); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) {/**/} }); itemView.setOnCreateContextMenuListener(this); } @Override public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) { contextMenu.setHeaderTitle("Select The Action"); contextMenu.add(0,666,0,"Delete Note"); }
}
片段
overrrides onContextItemSelected(MenuItem item){
//info is null
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
}
它还调用
registerForContextMenu(recyclerView);
顺序
- 我长按 NoteViewHolder,它会打开上下文菜单
- 我select"Delete"
- 使用 contextMenuInfo == null 调用 OnCreateContextMenu
- onSelectedContextItem 使用 item.getMenuInfo() == null 调用
如何获取非空的 menuInfo?
我应该自己创建菜单信息吗?如果是,在哪里?
PS,我看过这个post:How to create context menu for RecyclerView,我没有看到这个
的答案PS2 我也读过这个:http://androidheight.blogspot.fr/2015/03/recyclerview-widget-example-in-android.html,对我来说 new RecyclerAdapter().info = menuInfo;
这行似乎是错误的
谢谢
您需要在 RecyclerView 的 activity 中调用 registerForContextMenu()
。
这是一个我认为足够干净并为此实施的解决方案。
在适配器中,我创建了一个要实现的接口(由另一个 class,例如 activity 或我的片段)。
我将接口实现传递给适配器的CTOR。它可以以不同的方式传递,这只是这里的一个选择,因为我在片段或 activity 中创建了适配器,所以无论如何我都可以立即传递接口实现。 这个接口可以有你想要的方法。
public interface NoteListCommandListener{
void updateList();
void remove(Note n);
}
RVNoteAdapter(NoteListCommandListener noteListCommandListener){
super();
mNoteListCommandListener = noteListCommandListener;
}
我修改了 onBindViewHolder 方法,将接口实现从适配器传递给每个视图持有者。
@Override
public void onBindViewHolder(NoteViewHolder personViewHolder, int i) {
String name = notes.get(i).name;
personViewHolder.noteName.setText(name);
personViewHolder.noteListCommandListener= mNoteListCommandListener;
}
然后在视图持有者 CTOR 中,我使用 setOnCreateContextMenuListener,我在本地指定 class 因为当我调用 setOnMenuItemClickListener 时我仍然可以访问 noteListCommandListener 并且我可以直接调用它的任何函数。
public static class NoteViewHolder extends RecyclerView.ViewHolder
{
TextView noteName;
NoteListCommandListener noteListCommandListener;
public NoteViewHolder(View itemView) {
super(itemView);
noteName = (TextView)itemView.findViewById(R.id.note_name);
itemView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
contextMenu.setHeaderTitle("Select The Action");
contextMenu.add(0,42,0,"Delete Note").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
noteListCommandListener.remove(n);
return true;
}
});
}
});
}
}
优点是view holder的整个上下文菜单都在view holder中编码,很简单。 如果您需要动态更改上下文菜单(不是我的情况),则它的缺点是不能很好地分离。如果这样做,您可以避免在本地定义 2 class 并通过在 CTORS 中传递适当的参数来传递 class 在该范围之外定义。
谢谢大家的指教