@@ -97,6 +97,8 @@ public class Main extends AppCompatActivity {
9797 MaterialToolbar mToolbar ;
9898 BottomNavigationView mBottomNav ;
9999 CollapsingToolbarLayout mCollapsingToolbar ;
100+ com .google .android .material .appbar .AppBarLayout mAppBarLayout ;
101+ boolean mForceAppBarLifted = false ;
100102 OnBackPressedCallback mTabBackCallback ;
101103 OnBackPressedCallback mInnerNavCallback ;
102104
@@ -182,38 +184,43 @@ public void handleOnBackPressed() {
182184 mInnerNavCallback = new OnBackPressedCallback (false ) {
183185 @ Override
184186 public void handleOnBackPressed () {
185- if (! mNavigationStack . isEmpty ()) {
186- // Pop the previous entry
187- NavigationEntry entry = mNavigationStack . pop ();
188-
189- // Navigate back to the previous fragment
190- try {
191- Fragment previousFragment = entry . fragmentClass . newInstance ();
187+ // Use popBackStack to trigger the proper pop animations
188+ if ( getSupportFragmentManager (). getBackStackEntryCount () > 0 ) {
189+ getSupportFragmentManager (). popBackStack ();
190+
191+ // Pop our navigation stack too to keep track of titles
192+ if (! mNavigationStack . isEmpty ()) {
193+ NavigationEntry entry = mNavigationStack . pop ();
192194 updateTitle (entry .title );
195+ }
196+ // Collapse and keep AppBarLayout lifted (grey) during back navigation
197+ if (mAppBarLayout != null ) {
198+ mAppBarLayout .setExpanded (false , true ); // Collapse with animation
199+ mAppBarLayout .setLiftOnScroll (false );
200+ mAppBarLayout .setLifted (true );
201+ }
193202
194- getSupportFragmentManager ().beginTransaction ()
195- .setReorderingAllowed (true )
196- .setCustomAnimations (R .anim .fade_in , R .anim .fade_out )
197- .replace (R .id .fragment_container , previousFragment )
198- .commit ();
199-
200- // If stack is now empty, we're at root - disable this callback
201- // and update UI to hide back button
202- if (mNavigationStack .isEmpty ()) {
203- setEnabled (false );
204- if (mToolbar != null ) {
205- mToolbar .setNavigationIcon (null );
206- mToolbar .setNavigationOnClickListener (null );
207- }
208- // Re-enable tab back callback since we are at root
209- if (mBottomNav != null ) {
210- updateTabBackCallbackState (mBottomNav .getSelectedItemId ());
203+ // If back stack is now empty, we're at root - update UI
204+ if (getSupportFragmentManager ().getBackStackEntryCount () <= 1 ) {
205+ // Use a small delay to let the pop complete
206+ new android .os .Handler (android .os .Looper .getMainLooper ()).postDelayed (() -> {
207+ if (getSupportFragmentManager ().getBackStackEntryCount () == 0 ) {
208+ // Re-enable automatic lift-on-scroll at root
209+ mForceAppBarLifted = false ;
210+ if (mAppBarLayout != null ) {
211+ mAppBarLayout .setLiftOnScroll (true );
212+ }
213+ setEnabled (false );
214+ if (mToolbar != null ) {
215+ mToolbar .setNavigationIcon (null );
216+ mToolbar .setNavigationOnClickListener (null );
217+ }
218+ // Re-enable tab back callback since we are at root
219+ if (mBottomNav != null ) {
220+ updateTabBackCallbackState (mBottomNav .getSelectedItemId ());
221+ }
211222 }
212- }
213- } catch (Exception e ) {
214- e .printStackTrace ();
215- // Fallback: just disable and let other callbacks handle it
216- setEnabled (false );
223+ }, 50 );
217224 }
218225 } else {
219226 // Stack is empty, disable and let other callbacks handle it
@@ -281,12 +288,26 @@ public void navigateToFragment(Fragment fragment, String title) {
281288 mInnerNavCallback .setEnabled (true );
282289 }
283290
284- // Replace fragment WITHOUT adding to back stack
291+ // Replace fragment with slide animations
292+ // Parameters: enter, exit, popEnter, popExit
285293 getSupportFragmentManager ().beginTransaction ()
286294 .setReorderingAllowed (true )
287- .setCustomAnimations (R .anim .fade_in , R .anim .fade_out )
295+ .setCustomAnimations (
296+ R .anim .slide_in_right , // New fragment slides in from right
297+ R .anim .slide_out_left , // Old fragment slides out to left
298+ R .anim .slide_in_left , // When popping: old fragment slides in from left
299+ R .anim .slide_out_right // When popping: current fragment slides out to right
300+ )
288301 .replace (R .id .fragment_container , fragment )
302+ .addToBackStack (null )
289303 .commit ();
304+ // Collapse toolbar and force lifted (grey) state during inner navigation
305+ mForceAppBarLifted = true ;
306+ if (mAppBarLayout != null ) {
307+ mAppBarLayout .setExpanded (false , true ); // Collapse with animation
308+ mAppBarLayout .setLiftOnScroll (false );
309+ mAppBarLayout .setLifted (true );
310+ }
290311 }
291312
292313 public void resetToRoot (String title , boolean showImSafe ) {
@@ -325,6 +346,9 @@ void initializeUI() {
325346
326347 mImSafe = findViewById (R .id .safe );
327348 mBottomNav = findViewById (R .id .bottom_navigation );
349+
350+ // Get AppBarLayout reference for controlling lifted state during navigation
351+ mAppBarLayout = findViewById (R .id .app_bar );
328352
329353 mBottomNav .setOnItemSelectedListener (new NavigationBarView .OnItemSelectedListener () {
330354 @ Override
0 commit comments