Open bradmartin opened 5 years ago
After thinking about this and my original idea of a new flag.
Possibly something as simple as adding: skipCurrentModuleTransition?: boolean
to the NavigationTransition
interface would work.
When this is true
, the frame code can skip the setupCurrentFragment...()
methods that apply the exit/reenter transitions.
UPDATE: In trying this out, I'm not 100% certain but skipping the steps to apply a current fragment transition ends up not working through the transition logic. I'm sure there is some other stuff happening that I've not debugged yet. So perhaps, a simpler idea is to use fade
when skipCurrentModuleTransition: true
.? Of course, someone more familiar with the frame transitions might know why it's behaving odd when I don't apply the current frame
with a transition. Ideally, if that didn't have any negative impact on the stack then it seems like a simple "win" in terms of improving the UI/UX of NS Android apps.
I'm not sure on iOS ATM, I believe the slide transitions look and behave like they should on majority of iOS apps so this might end up being an android only transition property.
I'm looking to achieve the same transition. I tried to create it using a custom transition, which works decently well. I'm using Nativescript Vue, but it should be similar for other versions of Nativescript as well.
I created the file custom-transition.android.js
:
import { Transition, AndroidTransitionType } from "tns-core-modules/ui/transition";
import * as platform from "tns-core-modules/platform";
import lazy from "tns-core-modules/utils/lazy";
const screenWidth = lazy(() => platform.screen.mainScreen.widthPixels);
const screenHeight = lazy(() => platform.screen.mainScreen.heightPixels);
export default class CustomTransition extends Transition {
createAndroidAnimator(transitionType) {
const scaleValues = Array.create("float", 2);
const alphaValues = Array.create("float", 2);
switch (transitionType) {
case AndroidTransitionType.exit:
scaleValues[0] = 0;
scaleValues[1] = -200;
alphaValues[0] = 1;
alphaValues[1] = 0;
break;
case AndroidTransitionType.enter:
scaleValues[0] = screenHeight() / 2;
scaleValues[1] = 0;
alphaValues[0] = 0;
alphaValues[1] = 1;
break;
case AndroidTransitionType.popEnter:
scaleValues[0] = 0;
scaleValues[1] = 0;
alphaValues[0] = 0;
alphaValues[1] = 1;
break;
case AndroidTransitionType.popExit:
scaleValues[0] = 0;
scaleValues[1] = screenHeight();
alphaValues[0] = 1;
alphaValues[1] = 0;
break;
}
const objectAnimators = Array.create(android.animation.Animator, 2);
objectAnimators[0] = android.animation.ObjectAnimator.ofFloat(null, "translationY", scaleValues);
objectAnimators[1] = android.animation.ObjectAnimator.ofFloat(null, "alpha", alphaValues);
const animatorSet = new android.animation.AnimatorSet();
animatorSet.playTogether(objectAnimators);
animatorSet.setDuration(300);
animatorSet.setInterpolator(this.getCurve());
return animatorSet;
}
}
Then I added the following code to my app.js
file:
import CustomTransition from "./custom-transition"
const customTransition = new CustomTransition()
Vue.prototype.$customTransition = customTransition
Then call the transition in a .vue component like this:
this.$navigateTo(Item, {
transitionAndroid: {
instance: this.$customTransition
}
});
Which gives the following transition:
The only issue I'm having is that the AndroidTransitionType.enter
always appears below the AndroidTransitionType.exit
page. So unless I set alpha of the current page/fragment to 0, you don't see the new page/fragment transitioning in. Which isn't a deal breaker but a little annoying because I'd rather the header of the current page/fragment not turn white as the new page transitions in. I tried applying setZadjustment
in a few different ways but couldn't get anything to work.
Is your feature request related to a problem? Please describe. For years I've avoided the
slide
transition on Android because I've never used an app on android (in many years) that doesslide
transitions that look how NS does. So it looked odd to me to have a weird transition that most android users of native apps have never seen, a bit gimmicky at times. A lot of Android apps use theslideTop
style transition for the new activity/fragment, but the previous activity/fragment does not ALSO get the sameslideTop
for its exit transition. In NS, if you specifyslideTop
then the new fragment uses it forenter
and the current fragment uses it orexit
transition. The current fragment having that same transition applied is why I've never used theslide
transition personally.Describe the solution you'd like
Introduce a new flag into the
NavigationEntry
(maybe eventransitionAndroid
) that allows the user to DISABLE the current fragment having the exit/reenter transition applied to it. --- I prefer option 1 since it's not breaking and provides a very nice feature to improve NS Android.Open the API up for
navigate
to specify theenter/exit
transitions.Describe alternatives you've considered Hacking this in my core-modules with a custom fork 😄.
Additional context
For some context.
Notice in the Settings app, the
new
fragment/activity is using aslide
transition to enter. It is alsofading
but that's more work involved and outside the scope of this request. Notice how thecurrent
main fragment/activity does not have the same transition applied to it. Which is good on back nav because the previous page is visible to the user and they aren't watching some "reverse" transition.Here is how NS currently does the
slideTop
which has never been pleasing to me personally as I've never seen this on any Android app I use.I've just hacked core-modules a bit and applied
fade
on the current fragment to get this:Again, not perfect, and I might even prefer disabling the
exit
transition of thecurrent
fragment even more so the new one just slides on top instead of 'pushes' it out of the way.