我设法解决了在片段事务后在操作栏中出现额外图标的问题,但这是一个笨拙的解决方案,我想知道是否有更好的方法来解决它。
我有一个片段类层次结构,其中ContentFragment
是一个占据整个屏幕的抽象片段(操作栏除外),其子类提供额外的操作栏图标(通过各自的{{1} }和onCreateOptionsMenu()
方法)。例如。 onOptionsItemSelected()
ContentFragmentA
icon A
ContentFragmentB
icon B
,ContentFragmentB
ContentFragmentA
可能会或可能不会icon A
(如果是,{}}操作栏将并排包含icon B
和ContentFragmentA
,依此类推。
最初(在用户刚刚登录后)屏幕仅包含icon A
,操作栏包含ContentFragmentA
。当用户浏览应用程序时,其他内容片段(或更准确地说是片段事务)将添加到后台堆栈中,并且相应地在操作栏中添加或删除图标。
在用户决定注销之前,这一切都表现良好,提示应用程序清除整个后台堆栈(在最早的事务回滚后将LoginContentFragment
恢复)并立即添加New Profile icon
,对行动栏有icon A
的贡献。但是,此时此ContentFragmentA
也会显示在新的个人资料图标旁边,我不希望它被显示出来;这就是我面临的问题。当用户退出时它应该消失。
我通过像往常一样清除后台堆栈来解决这个问题,然后包含一个额外的交易,用setHasOptionsMenu(false)
替换icon A
一个空白的无图标内容片段,所以Login fragment
当空白片段被Menu.clear()
替换时,它将消失。但我觉得这很笨拙,并认为可能有更好的方法。
我已经尝试在片段替换步骤中调用ContentFragment
超类和Activity.supportInvalidateOptionsMenu()
中的Menu.clear()
但似乎都不起作用。 public abstract class ContentFragment extends Fragment {
public static interface Callbacks {
public abstract void setCurrentContentFragment(ContentFragment contentFragment);
}
protected Callbacks mCallbacks;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onStart() {
super.onStart();
mCallbacks = (Callbacks)getActivity();
mCallbacks.setCurrentContentFragment(this);
}
@Override
public void onStop() {
super.onStop();
mCallbacks = null;
}
public boolean handleBackPressed() {
return false;
}
}
特别会让所有图标消失,而不会在操作栏中留下任何图标。
有没有人知道其他选择?
相关代码:
ContentFragment.java:
public abstract class ContentFragmentA extends ContentFragment {
protected abstract void handleIconATouched();
...
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (menu.findItem(R.id.icon_a) == null) {
inflater.inflate(R.menu.icon_a, menu);
}
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.icon_a) {
handleIconATouched();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
}
ContentFragmentA.java:
public class BlankFragment extends LoggedInContentFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(false);
}
}
BlankFragment.java:
...
private void addContentFragmentNotAddingTransactionToBackStackIfCurrentFragment(ContentFragment fragment, boolean clearBackStack) {
// mCurrentContentFragment changes as the back stack is cleared, thus addToBackStack is calculated before the clearBackStack() step.
boolean addToBackStack = (false == clearBackStack && (mCurrentContentFragment != null && fragment.getClass() != mCurrentContentFragment.getClass()));
if (clearBackStack) {
clearBackStack();
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (addToBackStack) {
ft.addToBackStack(null);
}
ft.replace(R.id.container, fragment);
ft.commit();
getSupportFragmentManager().executePendingTransactions();
}
public void clearBackStack() {
while (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
}
// This is the step I would like to avoid
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, new BlankFragment());
ft.commit();
getSupportFragmentManager().executePendingTransactions();
}
...
在MainActivity.java中:
{{1}}
答案 0 :(得分:0)
我解决了这个问题。这是片段事务返回堆栈的问题。我混合了添加到后台堆栈的事务和那些没有的事务,这些导致后端堆栈弹出以意外的方式工作并防止碎片被正确删除,因此他们在操作栏中添加了额外的图标。问题在this SO question中解释。我采用的解决方案是this one。