Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get status of System Navigation Bar in Android

In Android a user can decide between two navigation modes:

  1. Gesture navigation > no system navigation bar will be shown, and any back swipe will trigger onWillPop
  2. Button navigation (with 2/3 buttons) > the system navigation bar will be shown, and only the back button will trigger onWillPop (there is no longer a back swipe detection)

In my application, whenever one of those two methods is used to 'go back', I'm trying to determine where the onWillPop callback came from: was it a back button press what triggered it, or was it a back swipe? I need this info in order to allow the user to perform certain actions in the app (the details are irrelevant to the question, but I basically need to decide whether to open a drawer or trigger a webview back navigation).

I haven't been able to obtain this information directly: is there a direct way to ascertain whether the back navigation action came from?

My second option was to try to get the status of the system navigation bar (shown/hidden) whenever onWillPop is called, so that I can guess where it came from. But I can't locate this information either. I saw I can get the kBottomNavigationBarHeight, which is constant independent of the bar's status, or the bottom padding with MediaQuery, which doesn't seem to be realiable and probably depends on the device and the size of the SafeArea.

Is there a way to get the current status of the navigation bar, or the user's preferences?

like image 453
Manu Avatar asked Oct 19 '25 13:10

Manu


2 Answers

I had the same issue and thankfully solved it without using the MethodChannel. In my case i wanted to hide white space when the Gesture Navigation is enabled in the mobile.

inside the build of 1st class,(in my case MyApp) write the code to check systemGestureInsets and pass their value to the splash screen. inside the initState of splash you can check if the left or right insets are non-zero then it means gesture navigation is enabled.

the complete code is given below:

This is First Class

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final EdgeInsets systemGestureInsets =
        MediaQuery.of(context).systemGestureInsets;
    return SplashScreen(
      gestureMode: systemGestureInsets.left > 0,
    );
  }
}

This is the class where you will check and hide the white space

class SplashScreen extends StatefulWidget {
  final bool gestureMode;

  const SplashScreen({super.key, required this.gestureMode});

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    if (widget.gestureMode) {
      //Only enables the overlays specified in the list
      SystemChrome.setEnabledSystemUIMode(
        SystemUiMode.manual,
        overlays: [SystemUiOverlay.top],
      );
    } else {
      SystemChrome.setEnabledSystemUIMode(
        SystemUiMode.manual,
        overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom],
      );
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

let me know if you have any questions regarding this.

like image 88
IKRAM UL HAQ Avatar answered Oct 21 '25 03:10

IKRAM UL HAQ


This method detects if the gesture navigation mode is enabled.

public static boolean isGestureNavigationMode(ContentResolver content) {
    return Settings.Secure.getInt(content, "navigation_mode", 0) == 2;
}

You can know if the user is using the gesture navigation mode simply by calling the method on a Boolean object. Example:

boolean gestures = isGestureNavigationMode(this.getContentResolver());

If the Boolean gestures is true the user is using navigation mode otherwise no.

like image 37
gcantoni Avatar answered Oct 21 '25 03:10

gcantoni



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!