Skip to content

Commit 9f7181f

Browse files
Merge pull request #251 from MihaiCristianCondrea/codex/refactor-graph-initialization-in-mainactivity
Preserve nav state across MainActivity recreation
2 parents 521b51c + b2f1fa2 commit 9f7181f

File tree

1 file changed

+70
-13
lines changed

1 file changed

+70
-13
lines changed

app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/main/MainActivity.java

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
public class MainActivity extends AppCompatActivity {
6363

6464
private static final long BACK_PRESS_INTERVAL = 2000;
65+
private static final String STATE_NAV_GRAPH_INITIALIZED = "state_nav_graph_initialized";
66+
private static final String STATE_LAST_PREFERRED_DESTINATION = "state_last_preferred_destination";
6567
private ActivityResultLauncher<IntentSenderRequest> updateActivityResultLauncher;
6668
private final SparseIntArray navOrder = new SparseIntArray();
6769
private ActivityMainBinding mBinding;
@@ -84,6 +86,8 @@ public void onResume(@NonNull LifecycleOwner owner) {
8486
private MainViewModel mainViewModel;
8587
private NavController navController;
8688
private int currentNavIndex;
89+
private boolean navGraphInitialized;
90+
private int lastPreferredStartDestination;
8791
private AppUpdateManager appUpdateManager;
8892
private InstallStateUpdatedListener installStateUpdatedListener;
8993
private long backPressedTime;
@@ -93,6 +97,11 @@ protected void onCreate(Bundle savedInstanceState) {
9397
SplashScreen.installSplashScreen(this);
9498
super.onCreate(savedInstanceState);
9599

100+
if (savedInstanceState != null) {
101+
navGraphInitialized = savedInstanceState.getBoolean(STATE_NAV_GRAPH_INITIALIZED, true);
102+
lastPreferredStartDestination = savedInstanceState.getInt(STATE_LAST_PREFERRED_DESTINATION, 0);
103+
}
104+
96105
updateActivityResultLauncher = registerForActivityResult(
97106
new ActivityResultContracts.StartIntentSenderForResult(),
98107
result -> {
@@ -222,16 +231,24 @@ private void observeViewModel() {
222231
getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment_activity_main);
223232
if (navHostFragment != null) {
224233
navController = navHostFragment.getNavController();
225-
NavGraph navGraph = navController.getNavInflater().inflate(R.navigation.mobile_navigation);
226-
navGraph.setStartDestination(uiState.defaultNavDestination());
227-
navController.setGraph(navGraph);
228234

229235
navOrder.put(R.id.navigation_home, 0);
230236
navOrder.put(R.id.navigation_android_studio, 1);
231237
navOrder.put(R.id.navigation_about, 2);
232-
androidx.navigation.NavDestination destination = navController.getCurrentDestination();
233-
if (destination != null) {
234-
currentNavIndex = navOrder.get(destination.getId());
238+
239+
int preferredStartDestination = uiState.defaultNavDestination();
240+
if (!navGraphInitialized) {
241+
NavGraph navGraph = navController.getNavInflater().inflate(R.navigation.mobile_navigation);
242+
navGraph.setStartDestination(preferredStartDestination);
243+
navController.setGraph(navGraph);
244+
navGraphInitialized = true;
245+
lastPreferredStartDestination = preferredStartDestination;
246+
} else {
247+
if (lastPreferredStartDestination == 0) {
248+
lastPreferredStartDestination = preferredStartDestination;
249+
} else if (preferredStartDestination != lastPreferredStartDestination) {
250+
navigateToPreferredDestination(preferredStartDestination);
251+
}
235252
}
236253

237254
NavOptions forwardOptions = new NavOptions.Builder()
@@ -248,11 +265,17 @@ private void observeViewModel() {
248265
.setPopExitAnim(R.anim.fragment_spring_exit)
249266
.build();
250267

268+
androidx.navigation.NavDestination destination = navController.getCurrentDestination();
269+
if (destination != null) {
270+
currentNavIndex = navOrder.get(destination.getId(), currentNavIndex);
271+
}
272+
251273
if (useRail) {
252-
if (mBinding.navRail != null) {
253-
NavigationUI.setupWithNavController(mBinding.navRail, navController);
254-
mBinding.navRail.setOnItemSelectedListener(item -> {
255-
if (item.getItemId() == navController.getCurrentDestination().getId()) {
274+
if (binding.navRail != null) {
275+
NavigationUI.setupWithNavController(binding.navRail, navController);
276+
binding.navRail.setOnItemSelectedListener(item -> {
277+
androidx.navigation.NavDestination currentDestination = navController.getCurrentDestination();
278+
if (currentDestination != null && item.getItemId() == currentDestination.getId()) {
256279
return true;
257280
}
258281
int newIndex = navOrder.get(item.getItemId());
@@ -265,7 +288,8 @@ private void observeViewModel() {
265288
} else {
266289
NavigationUI.setupWithNavController(navBarView, navController);
267290
navBarView.setOnItemSelectedListener(item -> {
268-
if (item.getItemId() == navController.getCurrentDestination().getId()) {
291+
androidx.navigation.NavDestination currentDestination = navController.getCurrentDestination();
292+
if (currentDestination != null && item.getItemId() == currentDestination.getId()) {
269293
return true;
270294
}
271295
int newIndex = navOrder.get(item.getItemId());
@@ -276,9 +300,9 @@ private void observeViewModel() {
276300
});
277301
}
278302

279-
setSupportActionBar(mBinding.toolbar);
303+
setSupportActionBar(binding.toolbar);
280304

281-
mBinding.toolbar.setNavigationOnClickListener(v -> {
305+
binding.toolbar.setNavigationOnClickListener(v -> {
282306
BottomSheetMenuFragment bottomSheet = new BottomSheetMenuFragment();
283307
bottomSheet.show(getSupportFragmentManager(), bottomSheet.getTag());
284308
});
@@ -297,6 +321,32 @@ private void observeViewModel() {
297321
}
298322

299323

324+
private void navigateToPreferredDestination(int preferredDestination) {
325+
if (navController == null) {
326+
return;
327+
}
328+
NavGraph graph = navController.getGraph();
329+
if (graph != null) {
330+
graph.setStartDestination(preferredDestination);
331+
}
332+
androidx.navigation.NavDestination currentDestination = navController.getCurrentDestination();
333+
if (currentDestination != null && currentDestination.getId() == preferredDestination) {
334+
lastPreferredStartDestination = preferredDestination;
335+
return;
336+
}
337+
if (graph == null) {
338+
lastPreferredStartDestination = preferredDestination;
339+
return;
340+
}
341+
NavOptions options = new NavOptions.Builder()
342+
.setPopUpTo(graph.getStartDestinationId(), true)
343+
.setLaunchSingleTop(true)
344+
.build();
345+
navController.navigate(preferredDestination, null, options);
346+
lastPreferredStartDestination = preferredDestination;
347+
}
348+
349+
300350
@Override
301351
public boolean onCreateOptionsMenu(android.view.Menu menu) {
302352
getMenuInflater().inflate(R.menu.menu_main, menu);
@@ -390,6 +440,13 @@ private void popupSnackbarForCompleteUpdate() {
390440
.show();
391441
}
392442

443+
@Override
444+
protected void onSaveInstanceState(@NonNull Bundle outState) {
445+
super.onSaveInstanceState(outState);
446+
outState.putBoolean(STATE_NAV_GRAPH_INITIALIZED, navGraphInitialized);
447+
outState.putInt(STATE_LAST_PREFERRED_DESTINATION, lastPreferredStartDestination);
448+
}
449+
393450
@Override
394451
protected void onDestroy() {
395452
if (installStateUpdatedListener != null && appUpdateManager != null) {

0 commit comments

Comments
 (0)