简体   繁体   中英

What is The proper way to animate a widget in flutter

I have tried a lot of packages like Animated Size And Fade and a widget like AnimatedSwitcher and nothing really worked, they just change the widget without animation .. here is my code :

                AnimatedSwitcher(
                    duration: Duration(milliseconds: 1),
                    child: isCompany
                        ? Container(
                      key: ValueKey<int>(0),
                      child: Padding(
                      padding: const EdgeInsets.fromLTRB(40, 0, 40, 0),
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: [
                                  TextField(
                                    decoration: InputDecoration(
                                        enabledBorder: UnderlineInputBorder(
                                          borderSide:
                                              BorderSide(color: Colors.white),
                                        ),
                                        prefixIcon: Image.asset(
                                            'assets/images/user_icon.png'),
                                        labelText: 'إسم المستخدم',
                                        labelStyle: TextStyle(
                                            color: Colors.white, fontSize: 18)),
                                  ),
                                  TextField(
                                    decoration: InputDecoration(
                                        enabledBorder: UnderlineInputBorder(
                                          borderSide:
                                              BorderSide(color: Colors.white),
                                        ),
                                        prefixIcon: Image.asset(
                                            'assets/images/password_icon.png'),
                                        suffixIcon: IconButton(
                                          icon: Image.asset(
                                              'assets/images/show_icon.png'),
                                          onPressed: () {},
                                        ),
                                        labelText: 'كلمة المرور',
                                        labelStyle: TextStyle(
                                            color: Colors.white, fontSize: 18)),
                                  ),
                                ],
                              ),
                            ),
                        )
                        : Container(
                      key: ValueKey<int>(1),
                      child: Padding(
                      padding: const EdgeInsets.fromLTRB(40, 40, 40, 40),
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: [
                                  TextField(
                                    decoration: InputDecoration(
                                        enabledBorder: UnderlineInputBorder(
                                          borderSide:
                                              BorderSide(color: Colors.white),
                                        ),
                                        prefixIcon: Image.asset(
                                            'assets/images/user_icon.png'),
                                        labelText: 'رقم الجوال',
                                        labelStyle: TextStyle(
                                            color: Colors.white, fontSize: 18)),
                                  ),
                                  TextField(
                                    decoration: InputDecoration(
                                        enabledBorder: UnderlineInputBorder(
                                          borderSide:
                                              BorderSide(color: Colors.white),
                                        ),
                                        prefixIcon: Image.asset(
                                            'assets/images/password_icon.png'),
                                        suffixIcon: IconButton(
                                          icon: Image.asset(
                                              'assets/images/show_icon.png'),
                                          onPressed: () {},
                                        ),
                                        labelText: 'كلمة المرور',
                                        labelStyle: TextStyle(
                                            color: Colors.white, fontSize: 18)),
                                  ),
                                ],
                              ),
                            ),
                        )
                ),

This is just changing widget with a click, no animation at all, and I need it to be like this video :

https://youtu.be/Uwe8hHkfd8I

AnimatedSwitcher just switches betwween the widget it displays.

One idea I had thinking about your problem is using a stack with two Positioned Items as your Buttons and one PositionedTransition, that translates between the position of your first and second Positioned Widgets when pressed.

Have a look at this example: https://api.flutter.dev/flutter/widgets/PositionedTransition-class.html

Now I had time to do a quick and easy example of my idea that looks like this:

在此处输入图片说明

(It does not lag - this is caused by the conversion of video to gif)

Code that you can copy paste as basis:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;

  final double containerWidth = 150.0;
  final double containerHeight = 50.0;
  final double padding = 20.0;
  final double borderWidth = 5.0;

  @override
  void initState() {
    super.initState();
    _controller =
        AnimationController(duration: Duration(seconds: 1), vsync: this);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: LayoutBuilder(builder: (context, constraints) {
        final Size biggest = constraints.biggest;
        return Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          color: Colors.white,
          child: Stack(
            children: [
              PositionedTransition(
                rect: RelativeRectTween(
                  begin: RelativeRect.fromSize(
                      Rect.fromLTWH(
                          padding, padding, containerWidth, containerHeight),
                      biggest),
                  end: RelativeRect.fromSize(
                      Rect.fromLTWH(biggest.width - containerWidth - padding,
                          padding, containerWidth, containerHeight),
                      biggest),
                ).animate(CurvedAnimation(
                  parent: _controller,
                  curve: Curves.easeInOut,
                )),
                child: Container(
                  width: containerWidth,
                  height: containerHeight,
                  decoration:
                      BoxDecoration(border: Border.all(width: borderWidth)),
                ),
              ),
              Positioned(
                  top: padding + borderWidth,
                  left: padding + borderWidth,
                  child: GestureDetector(
                    onTap: () {
                      _controller.reverse();
                    },
                    child: Container(
                      width: containerWidth - 2 * borderWidth,
                      height: containerHeight - 2 * borderWidth,
                      child: Center(
                        child: Text(
                          "Text1",
                          style: TextStyle(color: Colors.black, fontSize: 20),
                        ),
                      ),
                    ),
                  )),
              Positioned(
                  top: padding + borderWidth,
                  left: biggest.width - containerWidth - padding + borderWidth,
                  child: GestureDetector(
                    onTap: () {
                      _controller.forward();
                    },
                    child: Container(
                      width: containerWidth - 2 * borderWidth,
                      height: containerHeight - 2 * borderWidth,
                      child: Center(
                        child: Text(
                          "Text2",
                          style: TextStyle(color: Colors.black, fontSize: 20),
                        ),
                      ),
                    ),
                  )),
            ],
          ),
        );
      }),
    );
  }
}

Future work: To achieve what you want in the video you could use the AnimatedSwitcher you already tried to just alternate between the two Input fields depending on the button press.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM