rust-mobile/android-activity

Hide navigation bar (in native acitivity)

MarijnS95 opened this issue · 3 comments

Hey @rib, perhaps you have a better idea for this. With WindowManagerFlags::FULLSCREEN the status bar can be hidden (still available when swiping inwards from the top of the screen), and I'd like the same to happen on the navigation bar (bottom of the screen) instead of being drawn over my native activity. There doesn't seem to a be a setWindoWFlags() flag available to disable this (or that we can pass as the "remove" argument), and most answers seem to point to doing this via DecorView for which no native API is available (have to go through jni): https://stackoverflow.com/a/50831255

I can barely believe that native activities - intended for e.g. full-screen games - lack this functionality in an easily accessible manner. Did I miss something? Is this possible on GameActivity? If not, should we implement the above JNI logic on AndroidApp to be more easily accessible?

rib commented

GameActivity doesn't have any special support for this either. The examples I've seen just deal with hiding navigation bars in the Java subclass of GameActivity. E.g. that's what the rust-android-examples do.

Slightly related to this - I'm currently looking at binding the KeyCharacterMap java API so we'd have a way to access unicode characters for key presses (equivalent to getUnicodeChar) and that might help figure out a few boilerplate details for how we could potentially create some form of binding via JNI for this too.

@MarijnS95 hi, did you manage to solve it in a somewhat simple way? (eg. without creating a custom java class).
I am facing a similar problem with my game.
Another (worse) option would be to decrease the app window to accomodate the bottom bar. But disabling full screen flag doesn't seem to be working for me either.

I think it'd be great if that was a feature.

Following the link you sent, I managed to translate the JNI calls into Rust. However, since "only the original thread can touch its views", this call has to be made from the Java thread. I managed to hack this directly into native_activity/glue.rs in response to notify_focus_changed, but I'm not sure how this could be done properly.

It's probably possible to trigger this from the main thread somehow, feels hacky to me though. Triggering this in response to MainEvent::GainedFocus would mean crossing threads twice, which would make the timing unpredictable. I could imagine that the navigation bar might flicker once or something, as it may have already started showing by the time the function is run. Would have to try that.

Here's some ideas I had:

  • enable some form of configuration before starting the main thread, like setting a flag hide_navigation or even full event hooks to be run on the main thread
  • add a feature flag hide-navigation
    probably the simplest and least flexible solution
  • some form of run_on_java_thread(|| { ... })
  • use JNI to call Activity.runOnUiThread(Runnable)
    creating that Runnable seems like it would be quite involved