Skip to content

Navigation Transition Exit/Enter specific option #7700

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bradmartin opened this issue Aug 20, 2019 · 2 comments
Open

Navigation Transition Exit/Enter specific option #7700

bradmartin opened this issue Aug 20, 2019 · 2 comments

Comments

@bradmartin
Copy link
Contributor

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 does slide 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 the slideTop style transition for the new activity/fragment, but the previous activity/fragment does not ALSO get the same slideTop for its exit transition. In NS, if you specify slideTop then the new fragment uses it for enter and the current fragment uses it or exit transition. The current fragment having that same transition applied is why I've never used the slide transition personally.

Describe the solution you'd like

  1. Introduce a new flag into the NavigationEntry (maybe even transitionAndroid) 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.

  2. Open the API up for navigate to specify the enter/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 a slide transition to enter. It is also fading but that's more work involved and outside the scope of this request. Notice how the current 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.

settingsapp

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.
notsmooth

I've just hacked core-modules a bit and applied fade on the current fragment to get this:
slideandfade

Again, not perfect, and I might even prefer disabling the exit transition of the current fragment even more so the new one just slides on top instead of 'pushes' it out of the way.

@bradmartin
Copy link
Contributor Author

bradmartin commented Aug 20, 2019

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.

@Greene48
Copy link

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:

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants