Status Update
Comments
al...@google.com <al...@google.com>
[Deleted User] <[Deleted User]> #2
Jeremy, is this still an issue? I think the problem was that you had two transitions targeting the same View for the same action (e.g. two Slide() transitions).
ky...@gmail.com <ky...@gmail.com> #3
I have a similar issue with plain AnimatorSet:
set.start()
set.pause()
set.setCurrentPlayTime(100)
set.setCurrentPlayTime(0)
set.setCurrentPlayTime(100)
set.resume()
doesn't play animation in resume().
al...@google.com <al...@google.com> #4
Should clarify that if I filter out setCurrentPlayTime(0)
(or replace it with setCurrentPlayTime(1)
) it works well.
Also even with setCurrentPlayTime(0)
, onAnimationEnd
is notified with correct delay (as if the animation has played).
al...@google.com <al...@google.com> #5
@
I think that is intended for Animator. If you set the currentPlayTime
to 0 or the total duration the animator completes. We do some
rg...@google.com <rg...@google.com>
da...@gmail.com <da...@gmail.com> #6
Did some investigation on the Fragment side and it seems like the merged transition is targeting correctly.
Exiting Transition: Slide@aa9288e: tgts(android.widget.LinearLayout{f9add3d})
>>>>> ExitingViews <<<<<
View: android.widget.LinearLayout{f9add3d}
Entering Transition: Slide@35b8af: tgts(android.widget.LinearLayout{b7f24bc})
>>>>> EnteringViews <<<<<
View: android.widget.LinearLayout{b7f24bc}
Final merged transition: TransitionSet@7bc1c45:
TransitionSet@e133f9a:
Slide@aa9288e: tgts(android.widget.LinearLayout{f9add3d})
Slide@35b8af: tgts(android.widget.LinearLayout{b7f24bc})
merged transition passed to controlDelayedTransition: TransitionSet@7bc1c45:
TransitionSet@e133f9a:
Slide@aa9288e: tgts(android.widget.LinearLayout{f9add3d})
Slide@35b8af: tgts(android.widget.LinearLayout{b7f24bc})
Still digging.
ho...@eure.jp <ho...@eure.jp> #7
rg...@google.com <rg...@google.com> #8
So I have isolated this outside of fragment into something much simpler and I think it breaks down when it comes to the adding and removing of Views with animateToStart.
The attached sample is a simple add that goes between two screens BLUE
and GREEN
. It has code for both the 1.5.0-alpha03
and 1.5.0-alpha04
versions, but I think alpha04 is currently broken in another way so I will upload the alpha03 version here.
This is integrated with predictive back similar to how fragment is, so upon cancelling we call animateToStart
, then we do a beginDelayedTransition
on a 0
duration Fade()
and we reverse the view visibility back to what it was prior to starting the transition.
If you only do visibility, cancel always works the view never goes away, it is wonderful, but when you do adding and removing views like we need to in fragment it fails.
First the code for beginDelayedTransition goes from this:
TransitionManager.beginDelayedTransition(container, Fade().apply {
duration = 0
})
reverseViews()
to this:
TransitionManager.beginDelayedTransition(container, Fade().apply {
duration = 0
addListener(onEnd = {
reverseViews()
blueScreen.visibility = View.VISIBLE
greenScreen.visibility = View.VISIBLE
})
})
reverseViews(useVisibility = true)
We need to make this change because after the animateToStart()
view is still parented by the overlay, so we call reverseViews(useVisibility = true)
to only change the visibility and then once the transition finishes we can call reverseViews()
to parent the view properly, then we make both views visible again.
From our perspective after the 0
duration transition our views are back in the proper state, but they do not transition properly after a cancel.
If the app is doing this wrong and we can make the appropriate fixes, doing the same in fragment should resolve this. There is logging available that shows the state of the views when we start the transition.
vr...@deezer.com <vr...@deezer.com> #9
The API has changed since that project was created in a way that makes the API more robust. I'm hoping that has fixed this...
br...@monzo.com <br...@monzo.com> #10
There appears to be a problem with the order of operations. I'm going to look into fixing that.
rg...@google.com <rg...@google.com>
ti...@google.com <ti...@google.com> #11
Branch: androidx-main
commit e57dd5f9ac6cbb8cf83b221e2d5b3fbd3e88ce6b
Author: George Mount <mount@google.com>
Date: Thu Nov 09 14:33:53 2023
Fix animateToStart with Slide.
Fixes: 300157785
Slide was not repositioning the View to its proper
translation after animating it to the start position.
This fixes that so that it is moved.
Test: new test
Change-Id: I698f4dbcef46304f9aa545847d205f7b70c80d63
M transition/transition/src/androidTest/java/androidx/transition/SlideEdgeTest.java
M transition/transition/src/androidTest/java/androidx/transition/TranslationAnimationCreatorTest.java
M transition/transition/src/main/java/androidx/transition/TranslationAnimationCreator.java
br...@monzo.com <br...@monzo.com> #12
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.transition:transition:1.5.0-alpha05
en...@gmail.com <en...@gmail.com> #13
I'm getting a crash when using new version of ktx-core 1.16.0-alpha01
with fixed ViewCompat and ViewGroupCompat on API < 30. This is related to FragmentContainerView
:
java.lang.NullPointerException: Parameter specified as non-null is null: method androidx.fragment.app.FragmentContainerView.setOnApplyWindowInsetsListener, parameter listener
at androidx.fragment.app.FragmentContainerView.setOnApplyWindowInsetsListener(Unknown Source:2)
at androidx.core.view.ViewGroupCompat.dispatchApplyWindowInsets(ViewGroupCompat.java:255)
at androidx.core.view.ViewGroupCompat.dispatchApplyWindowInsets(ViewGroupCompat.java:264)
at androidx.core.view.ViewGroupCompat.dispatchApplyWindowInsets(ViewGroupCompat.java:264)
at androidx.core.view.ViewGroupCompat.dispatchApplyWindowInsets(ViewGroupCompat.java:264)
at androidx.core.view.ViewGroupCompat.dispatchApplyWindowInsets(ViewGroupCompat.java:264)
at androidx.core.view.ViewGroupCompat.dispatchApplyWindowInsets(ViewGroupCompat.java:264)
at androidx.core.view.ViewGroupCompat.dispatchApplyWindowInsets(ViewGroupCompat.java:264)
at androidx.core.view.ViewGroupCompat.lambda$installCompatInsetsDispatch$0(ViewGroupCompat.java:218)
at androidx.core.view.ViewGroupCompat$$ExternalSyntheticLambda1.onApplyWindowInsets(D8$$SyntheticClass:0)
at android.view.View.dispatchApplyWindowInsets(View.java:10499)
at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7191)
at android.view.ViewRootImpl.dispatchApplyInsets(ViewRootImpl.java:1925)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2030)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1721)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7598)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
at android.view.Choreographer.doCallbacks(Choreographer.java:790)
at android.view.Choreographer.doFrame(Choreographer.java:725)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
ti...@google.com <ti...@google.com> #14
Re
I think the @NonNull
annotation of androidx.fragment.app.FragmentContainerView.setOnApplyWindowInsetsListener
has been removed since
Do you mind upgrading your androidx.fragment version to 1.4.0-alpha09 or above? The latest version is
ti...@google.com <ti...@google.com> #17
Ah, you are right. It still requires a non-null object since the required type is not OnApplyWindowInsetsListener?
but OnApplyWindowInsetsListener
.
public override fun setOnApplyWindowInsetsListener(listener: OnApplyWindowInsetsListener) {
applyWindowInsetsListener = listener
}
Hi Jeremy,
Do you mind checking why androidx.fragment.app.FragmentContainerView.setOnApplyWindowInsetsListener
requires a non-null parameter? The restriction was added in
ap...@google.com <ap...@google.com> #18
Project: platform/frameworks/support
Branch: androidx-main
Author: Jeremy Woods <
Link:
Change the nullability of setOnApplyWindowInsetsListener
Expand for full commit details
Change the nullability of setOnApplyWindowInsetsListener
Since setOnApplyWindowInsetsListener overrides a method from the View
class which is in java and has no nullability, we did not know the
proper nullability.
It seems there are cases when the inset listener could indeed be null,
so we can make that nullable now.
RelNote: "FragmentContainerView's `setOnApplyWindowInsetsListener`
override now takes a null listener."
Test: All tests pass
Bug: 282790626
Change-Id: I575f0b5da72d096b14393afd9819ab66e061b002
Files:
- M
fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.kt
Hash: 415aeef3c0a44db3b614b717a65f8f028feef165
Date: Wed Jan 08 18:27:20 2025
jb...@google.com <jb...@google.com> #19
Hey Tiger,
I made it nullable again. We will release this in the next couple of weeks or so.
ti...@google.com <ti...@google.com> #20
Thank you Jeremy.
Since androidx.core
as mentioned at
If the issue mentioned at
de...@gmail.com <de...@gmail.com> #21
Any update on this to fix the crashing? Also does this new API will also fix the callback not being triggered after configuration change (orientation) for Android Tablet running on Android 21? We noticed another fragmented behavior between phone at tablet size devices where the setOnApplyWindowInsetsListener
callback is not being triggered in Fragments after configuration change.
Activity (callback is being triggered on both phone and tablet after configuration change)
ViewCompat.setOnApplyWindowInsetsListener(root) { _: View, insets: WindowInsetsCompat ->
// Return WindowInsetsCompat.CONSUMED if you don't want the window insets to keep passing down
// to descendant views including all views of Fragment(s) under this Activity
insets
}
Fragment with Jetpack Navigation (callback is being triggered regardless of Android version on phone size device after configuration change, but not on tablet running on Android 21)
ViewCompat.setOnApplyWindowInsetsListener(root) { _: View, insets: WindowInsetsCompat ->
// Return WindowInsetsCompat.CONSUMED if you don't want the window insets to keep passing down
// to descendant views including all views of Fragment(s) under this Activity
WindowInsetsCompat.CONSUMED
}
Also hoping
gr...@gmail.com <gr...@gmail.com> #22
Any chance this issue gets higher priority? It's a shame that Google is forcing developers to migrate to Android 15 and setup edge-to-edge while still having critical compatibility issues with older Android versions even in apps with relatively modern stack (Fragment + Compose)
ch...@gmail.com <ch...@gmail.com> #23
ti...@google.com <ti...@google.com> #24
Hi Jeremy,
Do you have any update about the new release?
jb...@google.com <jb...@google.com> #25
Build cut is this Wednesday and it will be released next week as part of Fragment 1.8.6
.
Description
According to docs
WindowInsetsCompat.CONSUMED
used inViewCompat.setOnApplyWindowInsetsListener
lambda should affect only View's direct children. This is working as expected on API >= 30, but on lower API's it affects whole View hierarchy making all other Views (even indirect children) ignore Insets.This behaviour is reproduced here:https://github.com/ai-corpo/InsetsTest . On API 30
NestedScrollView
respects bottom Inset even if topAppBar
returnedWindowInsetsCompat.CONSUMED
, but on lower API's same code makesNestedScrollView
ignore Insets.