如何为 FrameLayout 中的多个视图制作浮动上下文菜单?
Posted
技术标签:
【中文标题】如何为 FrameLayout 中的多个视图制作浮动上下文菜单?【英文标题】:How to make a Floating Context Menu for multiple views in a FrameLayout? 【发布时间】:2020-04-02 13:04:46 【问题描述】:我正在以这种方式将视图添加到FrameLayout
frameLayout.post(new Runnable()
@Override
public void run()
for (int i = 0; i < adapter.getCount(); i++)
View view = adapter.getView(i, null, frameLayout);
frameLayout.addView(view);
registerForContextMenu(view);
);
在onCreateContextMenu
中,我将选择的视图保存在一个变量中
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo)
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.fragment_page_lesson_menu, menu);
selectedView = v; // Saved view
但是在onContextItemSelected
中,当我尝试访问它时,它是null
@Override
public boolean onContextItemSelected(MenuItem item)
switch (item.getItemId())
case R.id.remove:
db.delete(selectedView.getID()); // Error selectedView is null
return true;
default:
return super.onContextItemSelected(item);
所有这些代码都在同一个 Fragment 类中。
public class MyFragment
private View selectedView;
// Code...
附加信息。
selectedView
不应为空,因为 onContextItemSelected 是
在 onCreateContextMenu 之后调用,对吗?
如果selectedView
被声明为static
,则没有NullPointerException
一切都很好。
frameLayout
只是在 onContextItemSelected
结果为空 (frameLayout.getChildCount()) 时
不是
【问题讨论】:
目前尚不清楚为什么要将Adapter
中的一堆View
s 堆叠在FrameLayout
中,但您似乎有多个Fragment
实例主动,有意或无意。为每个活动的Fragment
调用onContextItemSelected()
方法,直到返回true
以指示选择已被处理。如果您一次只应该运行一个 MyFragment
实例,那么您应该找出其他实例的来源。否则,将需要一些繁琐的工作来确保上下文菜单适用于给定的实例和View
。
@MikeM。非常感谢您的评论。我确实使用了FrameLayout
,因为我正在制作日历并且使用ListView
我无法很好地定位视图(view.setY
不起作用)。是的,Fragment
有多个实例,因为我使用的是ViewPager
。所以这就是问题所在。将selectedView
static
作为解决方案怎么样?
是的,大多数情况下这可能会起作用,但它有点老套,静态的View
引用是一个普遍的禁忌。可能一种更好但不太乏味的方法是首先在onContextItemSelected()
中对selectedView
进行空检查——如果它为空则返回false
——然后在onContextMenuClosed()
中设置selectedView = null;
。有了这个,你在onCreateContextMenu()
中设置selectedView = v;
,只有当前的Fragment
应该有一个非空的selectedView
。
@MikeM。它有效,谢谢。这就是我一直在寻找的
哎呀,我的建议搞错了。我注意到你覆盖了onOptionsMenuClosed()
而不是onContextMenuClosed()
,正如我所建议的那样。我刚刚意识到Fragment
没有onContextMenuClosed()
方法,所以显然你不能这样做,而且你的代码中仍然存在一个微妙的错误。完全摆脱onOptionsMenuClosed()
方法,使用后将selectedView = null;
移动到onContextItemSelected()
。你真的应该在case
和default
中都这样做,或者将其重构为最后只有一个return
语句,然后在此之前执行。
【参考方案1】:
来自 Mike M. 的评论
问题在于 MyFragment 存在多个实例,因为它位于 ViewPager 中。 (前面的代码在没有 ViewPager 的情况下工作)
现在的工作代码是:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo)
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.fragment_page_lesson_menu, menu);
selectedView = v;
@Override
public boolean onContextItemSelected(MenuItem item)
if(selectedView == null)
return false;
if (item.getItemId() == R.id.remove)
db.deleteLesson(selectedView.getId());
selectedView = null;
return true;
【讨论】:
以上是关于如何为 FrameLayout 中的多个视图制作浮动上下文菜单?的主要内容,如果未能解决你的问题,请参考以下文章