我有一个活动,A和两个片段,B和C.
在片段B和C中,我在setHasOptionsMenu(true)
方法中调用onCreate()
。
此外,对于每个我使用以下方法:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
getActivity().invalidateOptionsMenu(); // Doesn't help much...
menu.clear();
inflater.inflate(R.menu.menu_act_detail, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_favorite_act) {
Log.d(TAG, title);
return true;
} else if (item.getItemId() == R.id.action_visit_site_act) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
因此片段B和C的每个实例都有一个标题和URL。但是,当我向片段堆栈添加多个不同的B和C实例时,当我触发action_favorite_act
选项菜单项时,它会记录第一个实例的标题。
这是我用来向片段堆栈添加B或C实例的代码:
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = ActDetailFragment.newInstance(id);
fragmentManager.beginTransaction()
.add(R.id.flContent, fragment, id)
.addToBackStack(null)
.commit();
在这种情况下,id与属于每个实例的url字段相同。
示例行为:
我将一个B实例添加到片段堆栈中,其中title =“hello”和url =“test.com”
我触发action_favorite_act
菜单项并记录hello
我在片段堆栈中添加了一个C实例,标题=“world”和url =“site.com”
我触发action_favorite_act
菜单项并记录world
我将另一个B实例添加到片段堆栈中,其中title =“goodbye”和url =“another.com”
我触发action_favorite_act
菜单项,并记录hello
而不是goodbye
!
无论我添加多少个B或C实例,菜单项似乎都会追溯到第一个实例。因此,hello
和world
会被记录,而不是位于堆栈顶部的B和C实例的标题。如何获取堆栈顶部的菜单项以响应操作?
答案 0 :(得分:1)
我写了一个小应用程序试图复制你的问题,我可以。幸运的是,我为我的碎片使用了透明的背景,这很有帮助,因为这意味着我可以看到我的所有碎片一下子活着:
和你一样,我注意到当我选择选项菜单项时,我总是记录相同的信息(来自第一个片段)。
问题的根源似乎是片段类的每个实例对其菜单项使用相同的R.id
常量。所以你有例如您的活动中有三个片段B实例,但所有三个都可以处理R.id.action_favorite_act
上的点击。据推测,Activity只是迭代它的片段并将菜单事件传递给每个片段,直到有人处理它,因此第一个总是获胜。
您可以使用replace()
而不是add()
来解决此问题,因此任何时候只有一个给定片段类的实例存活并附加。
如果这不符合您的要求,我相信您必须为菜单项使用动态生成的ID,以便每个片段都有自己的项ID。