使额外的操作栏图标消失

时间:2015-07-14 18:32:01

标签: java android android-fragments android-actionbar android-actionbar-compat

我设法解决了在片段事务后在操作栏中出现额外图标的问题,但这是一个笨拙的解决方案,我想知道是否有更好的方法来解决它。

我有一个片段类层次结构,其中ContentFragment是一个占据整个屏幕的抽象片段(操作栏除外),其子类提供额外的操作栏图标(通过各自的{{1} }和onCreateOptionsMenu()方法)。例如。 onOptionsItemSelected() ContentFragmentA icon A ContentFragmentB icon BContentFragmentB ContentFragmentA可能会或可能不会icon A(如果是,{}}操作栏将并排包含icon BContentFragmentA,依此类推。

最初(在用户刚刚登录后)屏幕仅包含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}}

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。这是片段事务返回堆栈的问题。我混合了添加到后台堆栈的事务和那些没有的事务,这些导致后端堆栈弹出以意外的方式工作并防止碎片被正确删除,因此他们在操作栏中添加了额外的图标。问题在this SO question中解释。我采用的解决方案是this one