How to achieve some special effects for the switch of the fluent interface

background

We know that if you switch directly between pages, it will be stiff, make users feel very abrupt, and the user experience is not very good.

Therefore, generally, in order to achieve a smooth transition between pages, animation will be added.

In addition, sometimes we don't like the default animation of the system and want to be able to customize the animation.

Based on this, this article mainly describes how to add custom animation to the page switching of fluent.

Default effect

First, let's look at the default effect?

It looks good. The code is as follows:

import 'package:Flutter/material.dart';

void main() => runApp(MaterialApp(
  home: MyApp(),));

class MyApp extends StatelessWidget {
 // This widget is the root of your application.
 @override
 Widget build(BuildContext context) {
 return _getCenterWidget(RaisedButton(
  child: Text('Go to next page->'),onPressed: () {
   Navigator.of(context).push(_createRoute());
  }));
 }
}

Route _createRoute() {
 return MaterialPageRoute(builder: (BuildContext context) => Page2());
}

class Page2 extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return _getCenterWidget(Text('Page2'));
 }
}

Widget _getCenterWidget(Widget child) {
 return Scaffold(
 appBar: AppBar(),body: Center(
  child: child,),);
}

You can see that two pages myapp and Page2 have been created.

The first page myapp has a button, and the second page Page2 has a text.

The key switch is_ Createroute() is in the route creation method.

We click in the materialpageroute source code, and you can see

 @override
 Widget buildTransitions(BuildContext context,Animation<double> animation,Animation<double> secondaryAnimation,Widget child) {
 final PageTransitionsTheme theme = Theme.of(context).pageTransitionsTheme;
 return theme.buildTransitions<T>(this,context,animation,secondaryAnimation,child);
 }

With the initial comments, you can know that this is the default interface switching transition effect.

/// See also:
///
/// * [PageTransitionsTheme],which defines the default page transitions used
/// by [MaterialPageRoute.buildTransitions].

In addition, you can see that the default animation duration is 300ms, and we can't customize it.

 @override
 Duration get transitionDuration => const Duration(milliseconds: 300);

Next, let's talk about how to customize our interface, switch the transition effect, and customize the animation duration.

Custom animation

1. Set pageroutebuilder

From the above analysis, we know that the key is to create routing methods_ In createroute().

So let's modify it first. Instead of using the default materialpageroute, we use pageroutebuilder.

Route _createRoute() {
 return PageRouteBuilder(
  pageBuilder: (context,secondaryAnimation) => Page2(),transitionsBuilder:(context,child) {
  return child;
  }
 );
}

You can see that we specify the routing page through pagebuilder and the page transition effect through transitions builder.

In addition, you don't have to memorize the parameters here. We can see the source code by clicking it, as follows:

/// Signature for the function that builds a route's primary contents.
/// Used in [PageRouteBuilder] and [showGeneralDialog].
///
/// See [ModalRoute.buildPage] for complete deFinition of the parameters.
typedef RoutePageBuilder = Widget Function(BuildContext context,Animation<double> secondaryAnimation);

/// Signature for the function that builds a route's transitions.
/// Used in [PageRouteBuilder] and [showGeneralDialog].
///
/// See [ModalRoute.buildTransitions] for complete deFinition of the parameters.
typedef RouteTransitionsBuilder = Widget Function(BuildContext context,Widget child);

If we run the code, there should be no animation effect because we directly return to child. After we run, the effect is as follows:

2. Add tween and slidetransition

The default transition effect is from right to left. The customized demonstration effect here will transition from bottom to top.

It should be understood that tween is a linear interpolator between the start and end values.

In addition, by following up the transitions builder above, we can know that the value of his first animation parameter is 0.0 to 1.0.

Our side is from bottom to top, so the offset of the Y axis is from 1.0 to 0.0, which means that there is no offset from the whole page at the top in the vertical direction (already at the top).

Therefore, about tween and animation, we can get:

var begin = Offset(0.0,1.0);
var end = Offset(0.0,0.0);
var tween = Tween(begin: begin,end: end);
var offsetAnimation = animation.drive(tween);

Because we want to realize sliding, we can process and return the determined offset animation through slidetransition to get the modified routing code as follows:

Route _createRoute() {
 return PageRouteBuilder(
 transitionDuration: Duration(seconds: 5),pageBuilder: (context,child) {
  var begin = Offset(0.0,1.0);
  var end = Offset(0.0,0.0);
  var tween = Tween(begin: begin,end: end);
  var offsetAnimation = animation.drive(tween);

  return SlideTransition(
   position: offsetAnimation,child: child,);
  }
 );
}

The effects are as follows:

Seeing the above effect, some friends may have questions.

Question 1: I can understand that you open the page from bottom to top, but why is the return reversed from top to bottom?

We follow the source code of transitions builder, and you can see

 /// Used to build the route's transitions.
 ///
 /// See [ModalRoute.buildTransitions] for complete deFinition of the parameters.
 final RouteTransitionsBuilder transitionsBuilder;

We can follow (click) the buildtransitions in the comment and see the description of the animation as follows:

 /// * [animation]: When the [Navigator] pushes a route on the top of its stack,/// the new route's primary [animation] runs from 0.0 to 1.0. When the [Navigator]
 /// pops the topmost route this animation runs from 1.0 to 0.0.

We can see that the animation effects of entering and leaving the stack are opposite, and this is also in line with our cognition.

Question 2: the current effect is from bottom to top. If I want to realize from top to bottom, can I exchange the offset of begin and end?

In fact, if you understand what I said above

You will know what it would be like to change from 0.0 to 1.0.

Let's change it and explain it through the actual demonstration effect.

The modified code is as follows:

Route _createRoute() {
 return PageRouteBuilder(
  pageBuilder: (context,0.0);
  var end = Offset(0.0,1.0);
  var tween = Tween(begin: begin,);
  }
 );
}

Only the offset of begin and end is exchanged.

The operation effect is as follows:

Although we can see a clue, as we said earlier, the default animation duration is 300 ms, so it is relatively fast, which is not easy to analyze.

We can set the animation duration through the transitionduration property of pageroutebuilder.

Let's set 3S to see the following effect. The code is as follows:

Route _createRoute() {
 return PageRouteBuilder(
  transitionDuration: Duration(seconds: 3),);
  }
 );
}

The operation effect is as follows:

You see, it's really the opposite, from 0.0 from the top to 1.0 (100%) from the top.

So what if I want to enter from top to bottom?

We'll give you a picture. I'm sure you'll understand after reading it.

From this picture, we know that if we go from bottom to top, y should change from 1.0 to 0.0. If you want to go from top to bottom, y should change from - 1.0 to 0.0.

So we modify the code as follows:

Route _createRoute() {
 return PageRouteBuilder(
   transitionDuration: Duration(seconds: 3),child) {
    var begin = Offset(0.0,-1.0);
    var end = Offset(0.0,0.0);
    var tween = Tween(begin: begin,end: end);
    var offsetAnimation = animation.drive(tween);

    return SlideTransition(
     position: offsetAnimation,);
   }
 );
}

The operation effect is:

3. Point acceleration through curvetween

When we set the animation duration to 3S, we can obviously see that our animation speed seems to be uniform.

So if I want to change the speed of the animation, such as coming in fast and ending slow, can I?

The answer is yes.

We can realize this requirement through curvetween.

The focus is on the choice of curve, so what kind of curve should we choose?

In fact, one of my favorite points of FLUENT is that the code comments are detailed, and there are demo demonstrations.

Let's enter the source code of curves and take curves.ease as an example:

 /// A cubic animation curve that speeds up quickly and ends slowly.
 ///
 /// {@animation 464 192 https://Flutter.github.io/assets-for-api-docs/assets/animation/curve_ease.mp4}
 static const Cubic ease = Cubic(0.25,0.1,0.25,1.0);

The note says that the start is fast and the end is slow, and there is an mp4 link. Click to see the following effects:

We can see its change trend. Through the slope, we can see that it is fast in the early stage and slow in the later stage, and there are four animation effect previews on the right.

We set the curvetween code as follows:

var curveTween = CurveTween(curve: Curves.ease);

As you can see, it's easy to choose a change trend you want.

4. Combine tween and curvetween

This is also relatively simple. You can use the chain method provided by Tween, as follows:

var tween = Tween(begin: begin,end: end).chain(CurveTween(curve: Curves.ease));

In addition, offset (0.0,0.0) can be directly written as offset.zero.

The modified code is:

Route _createRoute() {
 return PageRouteBuilder(
   transitionDuration: Duration(seconds: 3),1.0);
    var end = Offset.zero;
    var tween = Tween(begin: begin,end: end).chain(CurveTween(curve: Curves.ease));

    return SlideTransition(
     position: animation.drive(tween),);
   }
 );
}

The operation effect is as follows:

5. Complete examples

With the above foundation, we can add animation effects in four directions. Of course, we don't delay. In addition, for the convenience of demonstration, you can directly open it and return it after delay 1s.

The code is as follows:

import 'package:Flutter/material.dart';

void main() => runApp(MaterialApp(
   home: MyApp(),));

class MyApp extends StatelessWidget {
 // This widget is the root of your application.
 @override
 Widget build(BuildContext context) {
  return _getCenterWidget(Column(
   mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
    _getBtn(context,'right in',Tween(begin: Offset(1.0,0.0),end: Offset.zero)),_getBtn(context,'left in',Tween(begin: Offset(-1.0,'bottom in',Tween(begin: Offset(0.0,1.0),'top in',-1.0),],));
 }
}

Widget _getBtn(BuildContext context,String textContent,Tween<Offset> tween) {
 return RaisedButton(
   child: Text(textContent),onPressed: () {
    Navigator.of(context).push(_createRoute(tween));
   });
}

Route _createRoute(Tween<Offset> tween) {
 return PageRouteBuilder(
   pageBuilder: (context,transitionsBuilder: (context,child) {
    return SlideTransition(
     position:
       animation.drive(tween.chain(CurveTween(curve: Curves.ease))),);
   });
}

class Page2 extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
  Future.delayed(Duration(seconds: 1),() {
   Navigator.of(context).pop();
  });
  return _getCenterWidget(Text('Page2'));
 }
}

Widget _getCenterWidget(Widget child) {
 return Scaffold(
  appBar: AppBar(),body: Center(
   child: child,);
}

The effects are as follows:

epilogue

Here, the transition between the flutter interfaces is basically clear.

Others, such as rotation, scaling, transparency and even combined animation, I believe that with the above foundation, you can also DIY by yourself.

The scaling effect attached here is as follows:

See GitHub for specific code:

flutter_ page_ transition

Reference link:

Well, the above is the whole content of this article. I hope the content of this article has a certain reference value for your study or work. Thank you for your support.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>