Status Update
Comments
[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).
il...@google.com <il...@google.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().
ap...@google.com <ap...@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).
ap...@google.com <ap...@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
ap...@google.com <ap...@google.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.
an...@google.com <an...@google.com> #7
Branch: androidx-main
commit 567b7459329d1ec8d27a8c6fe1c4a86442065d7d
Author: Jeremy Woods <jbwoods@google.com>
Date: Tue Sep 26 20:06:54 2023
Add additional logging for transitions
Adding more debug logging in transitions to track the entering and
exiting transitions as well as the final merged transition and its
targets.
Test: added logging
Bug: 300157785
Change-Id: I0d9ad72b865422493c6c895ddb6115abf85eed16
M fragment/fragment/src/main/java/androidx/fragment/app/DefaultSpecialEffectsController.kt
to...@gmail.com <to...@gmail.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.
il...@google.com <il...@google.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...
to...@gmail.com <to...@gmail.com> #10
There appears to be a problem with the order of operations. I'm going to look into fixing that.
to...@gmail.com <to...@gmail.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
il...@google.com <il...@google.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
to...@gmail.com <to...@gmail.com> #13
Was just commenting about the fact that those 2 events are not the same for dialog fragment despite the link you gave.
Since I'm rewriting a lot of stuff, I wonder what will be the final target for 1.3?
- onViewCreated will be attached for every cases
- onViewStateRestored will be attached for every cases
- This is still not determined and maybe not done for 1.3 so I should not bother yet.
il...@google.com <il...@google.com> #14
This bug is solely about onActivityCreated
. If you want to talk about onViewCreated
, let's move the conversation onto
If you want a foolproof signal for the View being attached, you should look at the View layer and doOnAttach
from core-ktx
. You don't need anything at the Fragment layer.
to...@gmail.com <to...@gmail.com> #15
I think there's a communication issue here :) My issue is about onActivityCreated
I don't care what is the replacement I just need to know what it will be :)
You tell me that onActivityCreated
and onViewCreated
are the same as called side by side, this is as proven unfortunately not true for dialog fragments that are fragments.
onActivityCreated
is the only callback that is made after the view is properly attached and things are all tied up.
Since you deprecate onActivityCreated
my question is unchanged what is / will be the proper callback for dialog fragment that ensure the same state as currently.
il...@google.com <il...@google.com> #16
I think the main communication issue is that I'm talking about the View moving to the attached state and you're talking about when the view has been added to its parent ViewGroup. While related (a View cannot be attached unless it is added to a ViewGroup that is attached), they are absolutely not the same thing.
For a non-dialog Fragment, the View is added to its container (but not always attached) right before onViewCreated()
is called. onViewCreated()
.
For a dialog Fragment, there is no container. FragmentManager does nothing before onViewCreated()
. This is likely to continue to be the case in Fragment 1.3.0 and beyond. DialogFragment
currently adds the View to the dialog in onActivityCreated()
, but still does not wait for the View to be attached. We'll need to continue to do that for backward compatibility, but will rewrite DialogFragment
to allow for an eventual removal of onActivityCreated()
entirely. That's the work I mentioned in #12.
Like I mentioned, you should really use doOnAttach
in onCreateView
or onViewCreated
if you want to get a callback for when your View has been attached and, by prerequisite, added to its parent. That will work consistently across all cases, Fragment, DialogFragment, or non-Fragment use cases.
to...@gmail.com <to...@gmail.com> #17
Thanks for clarification effectively I had no idea about added to parent being different from attached at the view level. Is there some doc page outside of raw API description that better cover that point?
ap...@google.com <ap...@google.com> #18
Branch: androidx-master-dev
commit f1cf08495ff78c020c05eed5e54ecc550e90c3df
Author: Jeremy Woods <jbwoods@google.com>
Date: Thu Mar 05 14:19:36 2020
Make onActivityCreated optional in DialogFragment
DialogFragment uses onActivityCreated() to help setup the dialog. Since
onActivityCreated() is being deprecated (aosp/1189651) we should find a
better home for the logic executed there.
Code concerning the view has been moved to the observe of the
viewLifecycleOwnerLiveData of the DialogFragment, and other
initialization can be done in onGetLayoutInflater when the Dialog is
initialized.
We will still support dialog setup in onActivityCreated for custom dialogs.
Test: all existing tests pass
BUG: 144309266
Change-Id: I832c596f2a6d6c2a4d77b97df15930d39bdedb9d
M fragment/fragment/src/androidTest/java/androidx/fragment/app/DialogFragmentTest.kt
M fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java
ap...@google.com <ap...@google.com> #19
Branch: androidx-master-dev
commit ab4247a7eb4c1bed603d42d84d8e6c5a5d604f58
Author: Jeremy Woods <jbwoods@google.com>
Date: Thu Mar 05 14:34:39 2020
Deprecate Fragment's onActivityCreated
The original purpose of the onActivityCreated() callback was to allow
fragment logic to be tied to the creation of its activity. We should no
longer be encouraging this coupling.
We should promote passing in external dependencies as construction
parameters using FragmentFactory. Code touching the fragment's view
should be done in onViewCreated() and other initialization code should
be in onCreate(). To receive a callback specifically when the activity's
onCreate() is complete, a LifeCycleObserver should be registered on the
activity's Lifecycle in onAttach(), and removed once the onCreate()
callback is received.
Test: ./gradlew checkApi
BUG: 144309266
Change-Id: Iba62d27bc6b87aa5048315a4cb90e5dcdf550114
M fragment/fragment/api/1.3.0-alpha02.txt
M fragment/fragment/api/current.txt
M fragment/fragment/api/public_plus_experimental_1.3.0-alpha02.txt
M fragment/fragment/api/public_plus_experimental_current.txt
M fragment/fragment/api/restricted_1.3.0-alpha02.txt
M fragment/fragment/api/restricted_current.txt
M fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentLifecycleTest.kt
M fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentLifecycleCallbacksDispatcher.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
jb...@google.com <jb...@google.com> #20
This has been fixed internally and will be available in the Fragment 1.3.0-alpha02 release.
sw...@gmail.com <sw...@gmail.com> #21
In my project, I currently use onActivityCreated()
to show/hide the app toolbar (with activity.supportActionBar.show()/activity.supportActionBarHide()).
Is it safe to move that logic to onViewCreated()
(as it is similar as onActivityCreated()
from my understanding of previous comments), or should I add a lifecycle observer on the Activity
?
il...@google.com <il...@google.com> #22
Re #21 - certainly sounds like you want onViewCreated()
.
ch...@gmail.com <ch...@gmail.com> #23
il...@google.com <il...@google.com> #24
Re #23 - sounds like onViewCreated()
is what you're looking for.
Description
Version used: 1.2.0-rc02
onActivityCreated() is a callback provided to Fragments ostensibly for when the activity is finished being created, but it ends up actually being tied into the Fragment view's lifecycle - it is actually called between onViewCreated() and onViewStateRestored() and can be called multiple times in cases where the Fragment is detached/re-attached or moved onto the back stack.
Besides being, at best, confusingly named, the original purpose of giving a callback after the Activity's onCreate() completes indicates a strong coupling between the logic in the Fragment and the logic running in the Activity's onCreate(), which is not a pattern we want to encourage. In general, Fragment should act independently from the Activity, being passed external arguments as constructor parameters via FragmentFactory.
We should deprecate onActivityCreated(), citing that the method is called directly after onViewCreated() and is not a one time call immediately after the activity is created as the name suggests. Code touching the Fragment's view should be in onViewCreated() and other initialization should be done in onCreate(). If the developer specifically wants a callback of when the Activity's onCreate() is complete, they should register a LifecycleObserver on the Activity's Lifecycle, removing it when they receive the onCreate() callback.