Status Update
Comments
jb...@google.com <jb...@google.com> #2
I'm marking this as "won't fix" as there's nothing Compose here can do, as this is a platform quirk that has been adjusted to be more predictable in recent API versions.
The crux of the issue here is the fitSystemWindows
in the extra View
, like you mentioned, and a platform change in API 30.
Prior to API 30, window insets were dispatched through the view hierarchy in a non-intuitive way: Rather than being a full breadth-first traversal, they would be dispatched in preorder. If the insets were consumed at any point (like if you use fitSystemWindows
), then the preorder would prevent insets from being dispatched to the rest of the view hierarchy. This is very unintuitive: It meant that sibling views (or views deeper in the tree) could stop later views from receiving the dispatch of insets.
In API 30, this behavior was changed to be more intuitive: Now, insets are dispatched in a top-down manner, so they can't be consumed in this weird, cross-tree way.
There's a couple solutions here:
- Avoid
fitSystemWindows
from views if you're handling insets manually - Override
dispatchApplyWindowInsets
in the view groups above where you havefitSystemWindows
defined, and manually perform the new, non-broken dispatching behavior. You can see a comparison of the two methods here:https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/ViewGroup.java;l=7341-7371;drc=6411c81462e3594c38a1be5d7c27d67294139ab8
to...@gmail.com <to...@gmail.com> #3
Using composable version 1.2.1, I could fix it using:
override fun onCreate(bundle: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(bundle)
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q){
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
}
}
Then statusBarsPadding works as expected on Api 29
il...@google.com <il...@google.com> #4
to...@gmail.com <to...@gmail.com> #5
Ahh I see what you mean now, thank you both! Setting the state parameter to RESUMED
in addMenuProvider
prevents the overlap as desired. It would be good to have a note about this in the documentation. It makes perfect sense now, but may not be immediately obvious to those looking to transition from the old API.
On a very minor note, there is still a delay as compared to setHasOptionsMenu
. In the old API, the menu icon is replaced smoothly and instantaneously, but with the new API there is a brief moment where neither icon is visible, causing a slight visual "flash". I assume that's unavoidable at the moment given the lifecycle state transitions, but it would be nice to recreate the old behavior.
ra...@gmail.com <ra...@gmail.com> #6
ra...@gmail.com <ra...@gmail.com> #7
In my case , when I click on the menu icon to show a dialog, the icon hides & coming back when screen resume, I can't use STARTED as it would overlap with other fragments menu options, Is there any workaround to fix hiding the icon, i'm aware that it is adding/removing provider based on lifecycle, but is there a workaround in this case?
view.requireActivity().addMenuProvider(
provider,
view.requireViewLifecycleOwner(),
Lifecycle.State.RESUMED
)
Description
I am trying to migrate from the deprecated
setHasOptionsMenu()
/onCreateOptionsMenu()
methods to the newaddMenuProvider()
/onCreateMenu()
methods in order to show an options menu from a fragment. Using the new API, I get an ugly delay/flicker of the icons in the action bar when navigating between two fragments that both implementMenuProvider
.I assume this is caused by asynchronous lifecycle callbacks: the new fragment's menu is probably inflated and added just before the old fragment's
Lifecycle.Event.ON_DESTROY
event triggers the removal of the old menu items, causing a brief moment when both menus are active simultaneously. However, I can't figure out how to avoid this behavior. I have tried calling bothremoveMenuProvider()
andinvalidateOptionsMenu()
fromonDestroyView()
in each fragment with no success. I also tried movingaddMenuProvider()
toonViewCreated()
instead ofonCreateView()
. The issue does not occur with the oldsetHasOptionsMenu()
API.Minimal reconstruction:
app:showAsAction="always"
.onCreateView()
: