Мне удалось обойти проблему, в которой дополнительный значок появляется на панели действий после транзакции фрагмента, но это было неуклюжие решения, и мне интересно, есть ли лучший способ решить его.Сделать лишнюю иконку панели действий удаляться
У меня есть иерархия классов фрагмента, в котором ContentFragment
является абстрактным фрагмент, который занимает весь экран (для панели действий, кроме) и его подклассы способствуют штриховым иконкам дополнительных действий (с помощью их соответствующих 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()
, в частности, просто запустит все значки, не оставив ни одного в панели действий.
Кто-нибудь знает альтернативу?
Соответствующий код:
ContentFragment.java:
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;
}
}
ContentFragmentA.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);
}
}
}
BlankFragment.java:
public class BlankFragment extends LoggedInContentFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(false);
}
}
В MainActivity.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();
}
...