Status Update
Comments
il...@google.com <il...@google.com> #2
I believe I'm having a related problem on certain devices. I set the systemBarBehavior as seen in line below:
WindowInsetsControllerCompat(window, main_container).systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
Although I'm setting the system bar behavior to BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
, it seems to be behaving as
BEHAVIOR_SHOW_BARS_BY_TOUCH
on some devices. After i hide the system UI (see fun
below) then touch the screen the bottom system navigation bar appears (the status bar remains hidden). When i swipe down from the top, the system status bar does appear transparent and goes away after a few seconds but the bottom system nav bar remains and isn't transparent.
Bug appears on: Galaxy s9+ (android 10), Galaxy Note 10+ (android 10). Bug does not appear on: Google Pixel 3a (android 11), Google Pixel 3 (android 11). I haven't tested on any other devices besides Galaxy s6 but that phone has hardware buttons so it doesn't apply.
Here's my code to go into full screen mode:
// Hide the app action bar, system status bar and system navigation bar
private fun hideSystemUI() {
supportActionBar?.hide()
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowInsetsControllerCompat(window, main_container).let { controller ->
controller.hide(WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.navigationBars())
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
an...@gmail.com <an...@gmail.com> #3
ap...@google.com <ap...@google.com> #4
Bug described above (where any touch on the screen reveals the bottom navigation bar) happens on Xiaomi Redmi Note 9S using Android 10 (MIUI 12) as well.
jb...@google.com <jb...@google.com> #5
an...@gmail.com <an...@gmail.com> #6
This is more of a missing feature as nobody has implemented the setSystemBarsBehavior
in Impl20
which is the implementation used on pre-30 devices. This shouldn't be such a big deal to implement but it is crucial for correct compat behavior. Please fix this asap!
ra...@gmail.com <ra...@gmail.com> #7
jb...@google.com <jb...@google.com> #8
Bug is real on every android 10 device wich i have on all alphas and beta core ctx versions.
Description
Version used: 2.1.0-rc01
Devices/Android versions reproduced on:
Proposal: Safe Arg generated Builder Classes should have default values inside.
This is actually not a bug for navigation component but a kind of side effect which can make this feature more versatile.
In my scenario, we were trying to use generated safe arg Builder classes to pass arguments to the fragments in our project, as the normal bundle arguments are not type safe and kinda messy to work with.
The project I'm working on is relative large, in our team we decided to migrate gradually to navigation component.
As a first step we wanted to put the fragment in a nav graph just to generate safe args so that we can use those classes to safely pass arguments to our existing fragment with fragment transaction and eventually use the graph in future point. So we are trying to use Safe arg as mentioned below:
ChoosePackageFragmentArgs args =
new ChoosePackageFragmentArgs.Builder("testName", "testPackage")
.setIsExtend(true)
.build();
ChoosePackageFragment fragment = new ChoosePackageFragment();
fragment.setArguments(args.toBundle());
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack(null)
.commit();
As you can see from the above example the "isExtend" property is optional and has a default value false which is set in the graph like this,
<argument
android:name="isExtend"
app:argType="boolean"
android:defaultValue="false" />
However if we use the generated safe arg builder class (ChoosePackageFragmentArgs) to pass the arguments to ChoosePackageFragment, without setting "isExtend" the ChoosePackageFragmentArgs.fromBundle(requireArguments()).getIsExtend() throws a NullPointerException because the builder doesn't set the default value when we call the args.toBundle() on the builder instance.
Moreover, when we try to call the getter method it can't find a value from the map, so it tries to cast a null value to (boolean), thus throwing the NullPointerException. Remember we're not using a NavController, just trying to take advantage of SafeArg feature.
This is the code from ChoosePackageFragmentArgs.Builder:
public class ChoosePackageFragmentArgs implements NavArgs {
....
@SuppressWarnings("unchecked")
public boolean getIsExtend() {
return (boolean) arguments.get("isExtend");
}
...
}
We were wondering why the default value is not present in the object. After digging for a while we've found that NavController.navigate() pulls the default values from NavAction.getDefaultArguments(); as we're not using NavComponent we're actually not getting the default value from Builder. Here's the code that pulls default args in NavComponent Library.
Code from NavController.java:
final NavAction navAction = currentNode.getAction(resId);
Bundle combinedArgs = null;
if (navAction != null) {
if (navOptions == null) {
navOptions = navAction.getNavOptions();
}
destId = navAction.getDestinationId();
Bundle navActionArgs = navAction.getDefaultArguments();
if (navActionArgs != null) {
combinedArgs = new Bundle();
combinedArgs.putAll(navActionArgs);
}
}
Suggestion:
If the safe arg plugin added the default values to the Builder while generating those SafeArgs Builder classes, the conventional fragment approach could get huge benefit out of it, and as these classes are accessible apis, I believe it makes more sense to have predictable behaviour for Builder classes as that seems like a standard predictable behaviour.