Status Update
Comments
ba...@gmail.com <ba...@gmail.com> #2
Branch: androidx-main
commit c2365dcfeb9064814282304f30f3eb86be71fdc7
Author: Dan Nizri <dniz@google.com>
Date: Wed Dec 20 16:33:08 2023
Fix Popup back handling on Android T/13+ when android:enableOnBackInvokedCallback="true"
Bug: 313702338
Bug: 318537200
Test: tested with android:enableOnBackInvokedCallback="true"
Change-Id: I7c7cef686ed9fbfd2d144c90040b13528f1675ed
M compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
yc...@gmail.com <yc...@gmail.com> #3
Is there remaining work for this feature request. Support for predictive back in Dialogs would allow Material3 to remove some Dialog forks and would be very helpful!
ri...@gmail.com <ri...@gmail.com> #4
Yeah, we probably want to investigate new API shapes here to take advantage of predictive back. No work ongoing yet though, needs prioritization
yu...@gmail.com <yu...@gmail.com> #5
st...@detroitlabs.com <st...@detroitlabs.com> #6
(recapping my chat with Ian)
The tricky part is that the onDismissRequest
is really the final signal and a chance for the app to just say 'nope, I don't want the dialog to dismiss' (since they own the state of 'should the dialog be shown or not' simply by either adding the Dialog to composition or leaving out of composition) - that's the just-in-time problem that the comment talks about. It would be very odd to have any kind of progress animation that doesn't actually lead to the dialog being dismissed when it is committed"
so really it needs to be a more holistic look at how to do dialogs and swap from a binary state (shown/not shown) to something that actually has something in between for cases like predictive back
na...@gmail.com <na...@gmail.com> #7
@Override
public Animation onCreateAnimation(int transit, final boolean enter, int nextAnim) {
switch (nextAnim){
case R.anim.fragment_scale_in:
case R.anim.fragment_scale_out:
zIndexValue = 0.0f;
break;
case R.anim.right_left_anim_x_left:
case R.anim.left_right_anim_x_right:
zIndexValue = 100.0f;
break;
}
if(nextAnim == 0) return super.onCreateAnimation(transit, enter, nextAnim);
Animation nextAnimation = AnimationUtils.loadAnimation(getContext(), nextAnim);
nextAnimation.setAnimationListener(new Animation.AnimationListener() {
private float mOldTranslationZ;
@Override
public void onAnimationStart(Animation animation) {
if(getView() != null){
mOldTranslationZ = ViewCompat.getTranslationZ(getView());
ViewCompat.setTranslationZ(getView(), zIndexValue);
}
}
@Override
public void onAnimationEnd(Animation animation) {
if(getView() != null){
//to make sure that the z index is set after the view tasks
getView().post(new Runnable() {
@Override
public void run() {
if(getView() != null) {
//set the original z index
ViewCompat.setTranslationZ(getView(), mOldTranslationZ);
}
}
});
getView().postDelayed(new Runnable() {
@Override
public void run() {
if(getView() != null) {
if(enter){
doneAnimationEnter();
}
}
}
}, 100);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
return nextAnimation;
}
ri...@gmail.com <ri...@gmail.com> #8
sk...@gmail.com <sk...@gmail.com> #9
sk...@gmail.com <sk...@gmail.com> #10
dn...@google.com <dn...@google.com> #11
Note: Please upload the files to google drive and share the folder to android-bugreport@google.com, then share the link here.
st...@gmail.com <st...@gmail.com> #13
dn...@google.com <dn...@google.com> #14
st...@gmail.com <st...@gmail.com> #15
gk...@gmail.com <gk...@gmail.com> #16
m4...@gmail.com <m4...@gmail.com> #17
dg...@gmail.com <dg...@gmail.com> #18
Should we use one of the workarounds posted here?
il...@google.com <il...@google.com> #19
While we can't fix the general case here within an unbundled library like Fragments, we can fix this in cases where the parent layout is a FrameLayout / extends FrameLayout by delaying the removal of the old View until after the animation completes under the assuption that children of a FrameLayout are suitably independent that animating one in while the other still exists in the layout is not an issue.
This should at least fix the issue for libraries built on top of Fragments such as Navigation.
[Deleted User] <[Deleted User]> #21
dc...@gmail.com <dc...@gmail.com> #22
ga...@gmail.com <ga...@gmail.com> #23
Ignore the fact that this library is a React Native library, it works the same for native apps.
ki...@gmail.com <ki...@gmail.com> #24
I've made a custom view group based on ScreenCoordinatorLayout
In bug case, Fragment.animateRemoveFragment() is called, but
ja...@planticle.com.au <ja...@planticle.com.au> #25
Still, this is was a frustrating and time consuming bug to work around, and I look forward to seeing a fix for this in the Jetpack Navigation library.
mi...@gmail.com <mi...@gmail.com> #26
We probably need to stick to activities if we want to follow material design guidelines.
I also look forward for this being fixed.
mi...@gmail.com <mi...@gmail.com> #27
mi...@gmail.com <mi...@gmail.com> #28
With the Navigation Component, and because of this limitation, is impossible to have an "slide on top" kind of transition.
ni...@webwag.com <ni...@webwag.com> #29
Currently, it's a FrameLayout which has this issue.
From NavHostFragment.java :
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
FrameLayout frameLayout = new FrameLayout(inflater.getContext());
// When added via XML, this has no effect (since this FrameLayout is given the ID
// automatically), but this ensures that the View exists as part of this Fragment's View
// hierarchy in cases where the NavHostFragment is added programmatically as is required
// for child fragment transactions
frameLayout.setId(getId());
return frameLayout;
}
je...@gmail.com <je...@gmail.com> #30
pe...@gmail.com <pe...@gmail.com> #31
Here may be a solution:
jb...@google.com <jb...@google.com>
ap...@google.com <ap...@google.com> #32
Branch: androidx-master-dev
commit 2534c731cc31a615e4584d74327521ec8c5a8aa7
Author: jbwoods <jbwoods@google.com>
Date: Thu Jun 20 12:42:37 2019
Draw exit animations first in FragmentContainerView
ViewGroups always draw exiting view animations last. For Fragments, this
means that the exiting Fragment is always on top of all others. There
can be no interaction with entering fragments, and there is the
possiblity of a "pop" when the exit animation finishes to reveal the
Fragment underneath.
FragmentContainerView overrides the dispatchDraw and drawChild method to
force all disappearing children to be drawn first. It overrides public
methods from ViewGroup to build the proper list of transitioning views
and disappearing child views.
Test: Added units tests, tested visually in app, ./gradlew checkApi
BUG: 37036000
Change-Id: I054eaf4ae234258bc7abec22c4c8e559a2c6be71
M fragment/fragment/api/1.2.0-alpha01.txt
M fragment/fragment/api/current.txt
M fragment/fragment/api/restricted_1.2.0-alpha01.txt
M fragment/fragment/api/restricted_current.txt
M fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
M fragment/fragment/src/androidTest/res/layout/fragment_container_view.xml
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.java
ge...@gmail.com <ge...@gmail.com> #33
[Deleted User] <[Deleted User]> #34
1. When going forward, I want exit animation to be bottom, and enter animation on top
2. When going backwards, I want exit animation on top, and enter animation on the bottom.
That way I could replicate iOS animation behavior where new fragment "comes on top" on previous, but when click back, I also want that fragment to disappear "from the top" and reveal previous fragment beneath it. android:zAdjustment sounds like something that should fix this problem, but is it working for Fragments and Navigation library?
Can anybody help me here?
il...@google.com <il...@google.com> #35
il...@google.com <il...@google.com>
bi...@gmail.com <bi...@gmail.com> #36
or...@gmail.com <or...@gmail.com> #37
"Fragments using exit animations are drawn before all others for FragmentContainerView. This ensures that exiting Fragments do not appear on top of the view."
Is our long national nightmare of improperly drawn transition animations over?
mo...@gmail.com <mo...@gmail.com> #38
^ This. I think ideally we should have a way of telling the Fragment its Z ordering during the animation. I know that are ways, but couldn't find any that works with the Navigation Components.
ma...@gmail.com <ma...@gmail.com> #39
I am experiencing the same issue for version 1.2.3 when using the "FragmentContainerView" and setting "EnterTransition" to a slide transition, and using an exisiting fade transition in "ExitTransition"?
So I am not using "FragmentTransaction.setCustomAnimations", but I guess it is supposed to work the same way?
[Deleted User] <[Deleted User]> #40
- works with setCustomAninations
- still does not work with setExitTransition / setEnterTransition
It looks like FragmentContainerView.startViewTransition is not called properly in the broken case, which causes that FragmentContainerView falls into the standard drawing path.
[Deleted User] <[Deleted User]> #41
The actual problem with setExitTransition / setEnterTransition is caused by fact that any subclass of Visibility transition (e.g. Fade, Slide, etc.), uses ViewOverlay to realize the animation when the exiting View is removed from its parent. And this is actually happening when performing replace() Fragment transaction. The trouble is than the entering view wont use ViewOverlay and will be effectively BELOW the exiting view :(
It is very sad that such basic usecases are still broken :(
I really cant believe that it was not catched earlier :(
As a workaround, one may try to write customized FragmentContainerVIew (cant inherit, because the one from Jetpack is final.... ) and write a customized set of Transitions that does not use ViewOverlay or use it in consistent manner preserving the z-order.
gc...@neptuneretailsolutions.com <gc...@neptuneretailsolutions.com> #42
Problem not fixed for Translations - suggest reopening.
My fix to allow enterTransition to act as if Hold() was working correctly. I don't enterTransition animate at all:
exitTransition = HoldBackground(resources).setDuration(duration)
enterTransition = Slide(Gravity.RIGHT).setDuration(duration)
With HoldBackground looking like this:
class HoldBackground(val resources : Resources) : Transition() {
init {
duration = resources.getInteger(android.R.integer.config_mediumAnimTime).toLong()
}
var inProgress = false
@Synchronized
override fun captureStartValues(transitionValues: TransitionValues) {
if(inProgress) return
transitionValues.view.also { exitingView ->
exitingView.parent.also { fragmentContainer ->
if(fragmentContainer is View && exitingView.width > 0 && exitingView.height > 0) {
inProgress = true
val previousBackground = fragmentContainer.background
val bitmap = Bitmap.createBitmap(
exitingView.width,
exitingView.height,
Bitmap.Config.ARGB_8888
)
exitingView.draw(Canvas(bitmap))
fragmentContainer.background = BitmapDrawable(resources, bitmap)
// Simple animator so timing matches developer animation scales
val animator = ValueAnimator.ofInt(0, 1).setDuration(duration)
animator.addListener(object : BlankAnimatorListener() {
override fun onAnimationEnd(animation: Animator?) {
fragmentContainer.background = previousBackground
inProgress = false
}
})
animator.start()
}
}
}
}
override fun captureEndValues(transitionValues: TransitionValues) {}
}
It's very likely stupidly resource intensive given it's creating a screen size bitmap... but it does happen to work.
yo...@gmail.com <yo...@gmail.com> #43
- Cancelling replace-fragment transitions, i.e. navigating up during a transition, causes the pop-exiting fragment to appear below the pop-entering fragment.
- It doesn't work with setExitTransition / setEnterTransition. Entering fragment is below the exiting fragment.
I have no words for this. Ill probably just use multiple-activities (instead of single-activity) and use activity transitions.
If someone has a solution, it will be much appreciated.
Description
ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="
android:shareInterpolator="true"
android:interpolator="@android:anim/decelerate_interpolator">
<translate android:fromXDelta="100%"
android:toXDelta="0%" android:fromYDelta="0%"
android:toYDelta="0%" android:duration="400">
</translate>
</set>
anim.slide_out_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="
android:shareInterpolator="true"
android:interpolator="@android:anim/decelerate_interpolator"
android:zAdjustment="bottom">
<translate android:fromXDelta="0%"
android:toXDelta="-50%" android:fromYDelta="0%"<!-- -50% shows the problem, 100% does not -->
android:toYDelta="0%" android:duration="400">
</translate>
</set>
(The zAdjustment tag does nothing)
The exiting fragment will be on top of the entering fragment, which is the opposite behavior than what is expected or useful. Currently, an exiting fragment must leave the frame completely, otherwise it will be on top of the entering fragment at the end of the animation, at which point in the last frame of the animation the exiting fragment will pop out of existence. The Z order of the fragments should be reversed or made customizable. The current z ordering offers no advantages.
I am trying to achieve the material effect of putting one "page" of a fragment on top of another while moving the exiting "page" somewhat to the left (50%), rather than 100% which would give the effect of just shoving the exiting "page" to the left, not putting it under the entering fragment. There are some work arounds described here
but they don't apply to my case.