Today to bring you is radial Hero animation, I was not sensitive to animation, just see when are ready to give up, ready to give up a bowl of chicken soup, finally through a morning of time, come out, I feel I am too cow!! Let’s take a look at the effect

  • rendering
  • Analysis steps
  • Page set up
  • Tangent square calculation
  • Page skipping:

rendering

Let’s take a look at today’s finished artwork:

Rendering (1.1) :

Analysis steps

First, analyze the steps:

  • 2 interfaces, a small image circular background, a large image square background wrapped with Card
  • Jump from a small circle page to a large square page
  • The outer layer of the large circle and square page is wrapped by Card
  • When a small circle jumps to a large page, the transparency changes from 0 to 1, as does a large square page
  • When the large square page returns, it changes from square to round
  • Water ripple effect when clicked

Page set up

The first step: zha we first no matter what square round, first come to the layout of 2 pages to write out

class Radial_hero_animaiton_demo_page extends StatefulWidget {
  @override
  _Radial_hero_animaiton_demo_pageState createState(a) =>
      _Radial_hero_animaiton_demo_pageState();
}

class _Radial_hero_animaiton_demo_pageState extends State<Radial_hero_animaiton_demo_page> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Radial Hero animation"), ), body: initRadialHeroBody(), ); }}/** * body layout */
  Widget initRadialHeroBody(a) {
    return Container(
        padding: EdgeInsets.all(30),
        // The layout is arranged to the left
        alignment: Alignment.bottomLeft,
        // Arrange the layout left and right
        child: Row(
          children: [
            // Circular layout
            ClipOval(
              child:  Material(
                color: Colors.teal,
                child: InkWell(
                  child: Image.network("https://raw.githubusercontent.com/flutter/website/master/examples/_animation/radial_hero_animation/images/chair-alpha.p ng",
                    width: 70,
                    height: 70,
                  ),
                  onTap: () {},
                ),
              ),
            )
          ],
        ));
  }
Copy the code

There is nothing wrong with this code. After a month of study, flutter will come to you without explanation, right

Square layout page:

import 'dart:math' as math;
class JumpHeroPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("JumpHeroPage page"),),//Center layout
        body: Center(
          // Use the card layout
          child: Card(
            child: Column(
              // Set the minimum width
              mainAxisSize: MainAxisSize.min,
              children: [
                SizedBox(
                  width: 300,
                  height: 300,
                  child: Container(
                    alignment: Alignment.center,
                    // Square layout
                    child: ClipRect(
                      child: Container(
                          width: 2 * (300 / 2 / math.sqrt2),
                          height: 2 * (300 / 2 / math.sqrt2),
                          child: Material(
                            color: Colors.teal,
                            // Water ripple effect
                            child: InkWell(
                              child: Image.network(
                                  "https://raw.githubusercontent.com/flutter/website/master/examples/_animation/radial_hero_animation/images/chair-alpha.p ng"), onTap: () { }, ), )), ), ), ), ], ), ), )); }}Copy the code

If you are unfamiliar with the layout, check out how Flutter develops Flutter layouts (1.3). In this article I have given a brief introduction to Flutter layouts.

Width: 2 * (300/2 / math.sqrt2), height: 2 * (300/2 / math.sqrt2), height: 2 * (300/2 / math.sqrt2),

Don’t worry, I will explain it in detail later.

Here it is important to note that in the use of Cloumn () component, this place need add mainAxisSize: mainAxisSize. Min, parameters, here on behalf of the meaning of the equivalent of android wrap_content will adaptive layout in the width and height: otherwise becomes rendering (1.2) Appearance:

Rendering (1.2);

The layout of the two pages and the ripple effect are completed here. Those who are not familiar with the ripple effect can learn about the ripple effect by referring to the Flutter Ink,InkWell, and InkResponse Ripple Implementation (2.3).

Step 2: Next, use Hero animation to complete the linkage of 2 pages

class Radial_hero_animaiton_demo_page extends StatefulWidget {
  @override
  _Radial_hero_animaiton_demo_pageState createState(a) =>
      _Radial_hero_animaiton_demo_pageState();
}

class _Radial_hero_animaiton_demo_pageState extends State<Radial_hero_animaiton_demo_page> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Radial Hero animation"),
      ),
      body: initRadialHeroBody(),
    );
  }

  /** * body layout */
  Widget initRadialHeroBody(a) {
    return Container(
        padding: EdgeInsets.all(30),
        alignment: Alignment.bottomLeft,
        child: Row(
          children: [
            Hero(
              tag: "RadialHeroAnimation".// Circular layout
              child: ClipOval(
                  child: Container(
                    child: Material(
                      color: Colors.teal,
                      child: InkWell(
                        child: Image.network("https://raw.githubusercontent.com/flutter/website/master/examples/_animation/radial_hero_animation/images/chair-alpha.p ng",
                          width: 70,
                          height: 70, ), onTap: () { }, ), ), )), ), ], )); }}Copy the code

Big square Hero animation:

class JumpHeroPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("JumpHeroPage page"),
        ),
        body: Center(
          // Use the card layout
          child: Card(
            child: Column(
              // Set the minimum width
              mainAxisSize: MainAxisSize.min,
              children: [
                SizedBox(
                  width: 300,
                  height: 300,
                  child: Hero(
                    tag: "RadialHeroAnimation".// Circular layout
                    child: ClipOval(
                      child: Container(
                        alignment: Alignment.center,
                        // Square layout
                        child: ClipRect(
                          child: Container(
                              width: 2 * (300 / 2 / math.sqrt2),
                              height: 2 * (300 / 2 / math.sqrt2),
                              child: Material(
                                color: Colors.teal,
                                child: InkWell(
                                  child: Image.network(
                                      "https://raw.githubusercontent.com/flutter/website/master/examples/_animation/radial_hero_animation/images/chair-alpha.p ng"), onTap: () { Navigator.of(context).pop(); },),),),),),),),),),)); }}Copy the code

Tangent square calculation

Here’s the key:

All the code looks fine and Hero works fine, but the question is why wrap a round layout around a square layout?

I have an idea. I’ll put the circular layout in the background so it’s easy to see:

Rendering (1.3)



As you can see from the renderings, it’s actually a square with a tangent square in it,

We used SizedBox() in our code to set the diameter of the circle to 300dp



300/2 is 150 so the radius of the circle is 150dp

Let’s start by explaining this code:

width: 2 * (300 / 2 / math.sqrt2),

height: 2 * (300 / 2 / math.sqrt2),

300/2 is the radius of the circle, and what is this mat.sqrt2?



Mat.sqrt2 is the square root of 2

Find the width of the tangent square by using the mathematical formula (radius/square root of 2)*2

Width: 2 * (300/2 / math.sqrt2), height: 2 * (300/2 / math.sqrt2),



It is actually the conversion between 2 round backgrounds, jump to the big circle, do not show the big circle background, but use the square background, so there is a small circle to the big square effect!

Page skipping:

Next add a click event to the image to complete the transparency animation jump between the two pages:

// Water ripple click event
onTap: () {
     Navigator.of(context).push(
        initPageRouteBuilder(),
       );
 },

Route<Object> initPageRouteBuilder(a) {
    return PageRouteBuilder(
      pageBuilder: (BuildContext context,
          Animation<double> animation,
          Animation<double> secondaryAnimation) {
        return JumpHeroPage();
      },
      // The time to open a new page
      transitionDuration: Duration(seconds: 2),
      // The time to close the page
      reverseTransitionDuration: Duration(seconds: 1),
      // Open the page animation
      transitionsBuilder: (BuildContext context,
          Animation<double> animation,
          Animation<double> secondaryAnimation,
          Widget child) {
        return FadeTransition(
          opacity:
          new Tween<double>(begin: 0, end: 1).animate( CurvedAnimation( parent: animation, curve: Curves.linear, ), ), child: child, ); }); }Copy the code

The jump here is the same as in the previous chapter :Flutter Hero animation (2.5), except that the jump page is different

Take a look at the current image:

Rendering (1.4) :

What’s left to get here is:

  • 2 interfaces, a small image circular background, a large image square background wrapped with Card
  • Jump from a small circle page to a large square page
  • The outer layer of the large circle and square page is wrapped by Card
  • When a small circle jumps to a large page, the transparency changes from 0 to 1, as does a large square page
  • When the large square page returns, it changes from square to round
  • Water ripple effect when clicked

Go here can be found, most have no problem, but why jump, why there should be oval action?

The same goes for the return, why square ==> oval ==> circle in the first place?

Here’s one property in Hero:

Hero(
  createRectTween: (Rect begin, Rect end) {
    return MaterialRectCenterArcTween(begin: begin, end: end);
   },
   tag:"".)Copy the code

Just add this line of code, and there is no jump ellipse transition; It’s a class inside a flutter, which is a helper class for making the change from square to round

Now that it’s all over, check out the final result:



Conclusion:

This chapter USES the radial Hero animation, I actually don’t know why I want to call the radial, I was watching the teacher in class for net, I was completely don’t understand his code, write that they grope and effect are same, the Hero in this and not to do, he is on the background of the picture after, by the change of the small circle to circle, show in the great circle is tangent is Square, big circle also don’t give the background, only give the tangent square background, so when you transition, you have this effect. Code I also did not encapsulate, readability is still very high, interested friends can try to encapsulate. Hahaha, I am so good, I feel like a god today ~

The complete code

Chapter 1 :Flutter Hero animation (2.5)

Next chapter :Flutter custom AppBar, Wheel Banner(2.7)

Original is not easy, your thumbs up and comments are my biggest support, leave your thumbs up ~


\

The following is my official account. I usually post some knowledge about Andorid and FLUTTER. It is mainly used to record some knowledge about flutter during work development