2

Мне удалось обойти проблему, в которой дополнительный значок появляется на панели действий после транзакции фрагмента, но это было неуклюжие решения, и мне интересно, есть ли лучший способ решить его.Сделать лишнюю иконку панели действий удаляться

У меня есть иерархия классов фрагмента, в котором 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(); 
} 

... 

ответ

0

Я решил эту проблему. Это была проблема с предыдущим стеком транзакций фрагмента.Я смешивал транзакции, которые были добавлены в задний стек с теми, которые не были, и это вызывало неожиданное срабатывание обратного стека и предотвращение удаления фрагментов, поэтому они добавляли дополнительные значки в панель действий. Проблема объясняется в this SO question. Решение, которое я принял, - this one.

Смежные вопросы