getBackStackEntryCount возвращает 0 при воссоздании Activity - PullRequest
0 голосов
/ 17 февраля 2020

Я знаю, что это должно быть просто, и я, вероятно, не вижу решения. Вот краткое описание того, что у меня есть: SignInActivity (AppCompatActivity) - обрабатывать проверку подлинности Firebase, в случае успеха вызывает метод:

private void onAuthSuccess(FirebaseUser user) {
    // Go to MainActivity
    startActivity(new Intent(SignInActivity.this, MainActivity.class));
    finish();
}

MainActivity (AppCompatActivity) - обрабатывать меню для приложения, это меню в В частности, фрагменты с кнопками. При нажатии кнопки я меняю фрагмент, содержащий другие кнопки. Примерно так:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager()
                .beginTransaction()
                .setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_left)
                .replace(R.id.fragmentContent, MainMenuFragment.newInstance())
                .commitNow();
    }

    getSupportFragmentManager().addOnBackStackChangedListener(new 
        FragmentManager.OnBackStackChangedListener() {
            @Override
            public void onBackStackChanged() {
                int stackHeight = getSupportFragmentManager().getBackStackEntryCount();
                getSupportActionBar().setHomeButtonEnabled(stackHeight > 0);
                getSupportActionBar().setDisplayHomeAsUpEnabled(stackHeight > 0);
            }
        });
}

public void replaceFragments(Class fragmentClass, boolean isBack) {
    Fragment fragment = null;
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();

    if (isBack) {
        ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
    } else {
        ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right);
    }

    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        fragment = null;
        e.printStackTrace();
    }

    if (fragment != null) {
        ft.replace(R.id.fragmentContent, fragment);
        ft.addToBackStack(fragmentClass.getName());
        ft.commit();
    }
}

MainMenuFragment (Fragment) - первый набор опций, несколько кнопок друг над другом. В зависимости от нажатой кнопки будет вызываться MainActivity.replaceFragment, передавая следующий фрагмент в go.

public class MainMenuFragment extends Fragment {
    private static final String TAG = "MainMenuFragment";

    public static MainMenuFragment newInstance() {
        return new MainMenuFragment();
    }

    public MainMenuFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_main_menu, container, false);

        final Button btnAssets = view.findViewById(R.id.btnAssets);
        final Button btnAudit = view.findViewById(R.id.btnAudit);

        btnAssets.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "BtnAssets_onClick");
                ((MainActivity)getActivity()).replaceFragments(AssetMenuFragment.class);
            }
        });

        btnAudit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "BtnAudit_onClick");
                ((MainActivity)getActivity()).replaceFragments(AuditMenuFragment.class);
            }
        });
        return view;
    }
}

AssetMenuFragment и AuditMenuFragment в значительной степени совпадают с MainMenu, только текст для кнопок и некоторые изменения в макете.

Когда я использую приложение, я сначала регистрируюсь, что приводит меня к MainActivity, который загружает MainMenuFragment в onCreate. Там у меня есть две кнопки: одна для go для AssetMenuFragment, а другая для go для AuditMenuFragment, они заменяют фрагмент соответствующими макетами. Если я нажму кнопку «Актив» после замены фрагмента из-за:

getSupportActionBar().setHomeButtonEnabled(stackHeight > 0);
getSupportActionBar().setDisplayHomeAsUpEnabled(stackHeight > 0);

Мне будет показана стрелка назад на go назад к MainMenuFragment. Все работает как положено.

Теперь проблема! Если я нахожусь в этом AssetMenuFragment, с моей красивой стрелкой назад, отображаемой на панели ActionBar, и решил нажать кнопку «Квадрат» на устройстве, которое, вероятно, запускает onPause и onStop, и они снова нажимают на приложение, которое запустится onCreate и onStart снова, моя стрелка назад исчезает, потому что теперь int stackHeight = getSupportFragmentManager().getBackStackEntryCount(); равно нулю.

Как я могу сохранить свой стек и восстановить его позже, чтобы я мог нажать обратно на AssetMenuFragment и go вернуться к MainMenuFragment .

Много читать, но я буду признателен за помощь, спасибо!

1 Ответ

0 голосов
/ 17 февраля 2020

В конце концов я понял, что это должно быть что-то простое.

Обе проверки верны.

getSupportActionBar().setHomeButtonEnabled(stackHeight > 0);
getSupportActionBar().setDisplayHomeAsUpEnabled(stackHeight > 0);

Проблема заключалась в том, что я не проверял их на onCreate, только на событии getSupportFragmentManager().addOnBackStackChangedListener.

Вот теперь MainActivity:

private ActionBar actionBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getSupportFragmentManager()
                .beginTransaction()
                .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
                .replace(R.id.fragmentContent, MainMenuFragment.newInstance())
                .commitNow();
    }

    actionBar = getSupportActionBar();
    updateActionBarBackButton();

    getSupportFragmentManager().addOnBackStackChangedListener(new 
        FragmentManager.OnBackStackChangedListener() {
            @Override
            public void onBackStackChanged() {
                updateActionBarBackButton();
            }
        });
}

private void updateActionBarBackButton() {
    int stackHeight = getSupportFragmentManager().getBackStackEntryCount();
    getSupportActionBar().setHomeButtonEnabled(stackHeight > 0);
    getSupportActionBar().setDisplayHomeAsUpEnabled(stackHeight > 0);
}

...