IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Flutter实战项目《模仿京东App》第七篇 动画 -> 正文阅读

[游戏开发]Flutter实战项目《模仿京东App》第七篇 动画

概要

  • 颜色变换动画
  • 根据父元素定位动画

一、AnimatedOpacity透明度动画组件

opacity

透明度

duration

动画时间

child

子节点
curve动画曲线
onEnd动画结束回调
alwaysIncludeSemantics

import 'package:copy_jd/component/custom.bar.dart';
import 'package:flutter/material.dart';

import '../../component/toast.dart';

class TestToast extends StatefulWidget {
  const TestToast({Key? key}) : super(key: key);
  static const routeName = '/testtoast'; 
  @override
  State<TestToast> createState() => _TestToastState();
}

class _TestToastState extends State<TestToast> {
// FocusNode focusNode = FocusNode();
  FocusNode _uNameNode = FocusNode();
  FocusNode _pwdNode = FocusNode();
  TextEditingController _uNameController = TextEditingController();
  TextEditingController _pwdController = TextEditingController();
  GlobalKey<FormState> _formKey = new GlobalKey<FormState>();

  late String _name;

  late String _password;
  late bool normal =false;

  void _forSubmitted(BuildContext context) {
    setState(() {
      normal =!normal;
    });
    Toast.show(context:context,message:'提示');
    var _form = _formKey.currentState;

    if (_form!.validate()) {
      _form.save();
      print(_name);
      print(_password);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
    appBar: const CustomBar(),
    body: SingleChildScrollView(
       child: Container(
          padding: const EdgeInsets.all(16.0),
          child:
           Form(
            key: _formKey,
            onChanged: (){
              
            },
            child: 
            Column(
              children: <Widget>[
                 TextFormField(
                  decoration: const InputDecoration(
                    labelText: 'Your Name',
                  ),
                  onSaved: (val) {
                    _name = val!;
                  },
                ),
                 TextFormField(
                  decoration:  const InputDecoration(
                    labelText: 'Password',
                  ),
                  obscureText: true,
                  validator: (val) {
                    return val!.length < 4 ? "密码长度错误" : null;
                  },
                  onSaved: (val) {
                    _password = val!;
                  },
                  onChanged: (e){
                    print(e);
                  },
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 28.0),
                  child: Row(
                    children: <Widget>[
                      Expanded(
                        child: ElevatedButton (
                            child: const Text('登录'),
                            onPressed:(){
                              _forSubmitted(context);
                            },
                        )
                      )
                    ]
                  ),
                ),
                AnimatedOpacity(
                  opacity: normal ? 0.0 : 1.0,
                  duration: Duration(milliseconds: 500),
                  child: Container(
                    height: 100,
                    color: Colors.blue,
                  ),
                ),
              ],
            ),
          ),
        ),
     ),
    );
  }
}

二、通过控制器实现颜色过渡

????????

import 'package:flutter/material.dart';

class TestToast extends StatefulWidget {
  const TestToast({Key? key}) : super(key: key);
  static const routeName = '/testtoast'; 
  @override
  State<TestToast> createState() => _TestToastState();
}

class _TestToastState extends State<TestToast> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation _animation;
  
  @override
  void initState() {
    super.initState();

    //创建动画控制器
    _animationController = AnimationController(
      vsync: this,
      duration:const Duration(milliseconds: 1000),
    );
    //添加动画执行刷新监听
    _animationController.addListener(() {
      setState(() {});
    });
    //添加动画状态监听
    _animationController.addStatusListener((status) {
      //获取动画执行状态
      AnimationStatus status = _animationController.status;

      //动画正向执行完成状态
      if (status == AnimationStatus.completed) {
        //反向开启动画
        _animationController.reverse();
      } else if (status == AnimationStatus.dismissed) {
        //动画初始未执行或者是动画反向执行完成

        //正向开始执行动画
        _animationController.forward();
      }
    });
    //颜色动画变化
    _animation = ColorTween(begin: Colors.green, end: Colors.red)
        .animate(_animationController);

    //添加到事件队列
    Future.delayed(Duration.zero, () {
      _animationController.forward();
    });
  }

  late double _opacity = 1.0;
  late Matrix4 _transform = Matrix4.translationValues(0, 0, 0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Center(
            child: Container(
              width: 200,
              height: 200,
              color: _animation.value,
            )
        ],
      )
    );
  }
}

三、通过AnimatedContainer实现 CSS3

import 'package:flutter/material.dart';

class TestToast extends StatefulWidget {
  const TestToast({Key? key}) : super(key: key);
  static const routeName = '/testtoast'; 
  @override
  State<TestToast> createState() => _TestToastState();
}

class _TestToastState extends State<TestToast>{
  late double _opacity = 1.0;
  late Matrix4 _transform = Matrix4.translationValues(0, 0, 0);

  void _onTapHandle() {
    setState(() {
      _opacity = _opacity == 1.0 ? 0.0 : 1.0;
      _transform = _opacity == 0.0
          ? Matrix4.translationValues(-300, 0, 0)
          : Matrix4.translationValues(0, 0, 0);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          AnimatedContainer(
            duration: Duration(milliseconds: 500),
            transform: _transform,
            child: AnimatedOpacity(
              opacity: _opacity,
              duration: Duration(milliseconds: 500),
              child: Container(
                alignment: Alignment.center,
                width: 100,
                height: 50,
                color: Colors.pink,
              ),
            ),
          ),
          TextButton(
            onPressed: _onTapHandle,
            child: Text("改变")
          )
        ],
      )
    );
  }
}

四、官网实例

import 'dart:math';

import 'package:flutter/material.dart';

class TestToast extends StatefulWidget {
  const TestToast({Key? key}) : super(key: key);
  static const routeName = '/testtoast'; 
  @override
  State<TestToast> createState() => _TestToastState();
}

class _TestToastState extends State<TestToast> with SingleTickerProviderStateMixin {
  // Define the various properties with default values. Update these properties
  // when the user taps a FloatingActionButton.
  double _width = 50;
  double _height = 50;
  Color _color = Colors.green;
  BorderRadiusGeometry _borderRadius = BorderRadius.circular(8);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('AnimatedContainer Demo'),
        ),
        body: Center(
          child: AnimatedContainer(
            // Use the properties stored in the State class.
            width: _width,
            height: _height,
            decoration: BoxDecoration(
              color: _color,
              borderRadius: _borderRadius,
            ),
            // Define how long the animation should take.
            duration: const Duration(seconds: 1),
            // Provide an optional curve to make the animation feel smoother.
            curve: Curves.fastOutSlowIn,
          ),
        ),
        floatingActionButton: FloatingActionButton(
          // When the user taps the button
          onPressed: () {
            // Use setState to rebuild the widget with new values.
            setState(() {
              // Create a random number generator.
              final random = Random();

              // Generate a random width and height.
              _width = random.nextInt(300).toDouble();
              _height = random.nextInt(300).toDouble();

              // Generate a random color.
              _color = Color.fromRGBO(
                random.nextInt(256),
                random.nextInt(256),
                random.nextInt(256),
                1,
              );

              // Generate a random border radius.
              _borderRadius =
                  BorderRadius.circular(random.nextInt(100).toDouble());
            });
          },
          child: const Icon(Icons.play_arrow),
        ),
      ),
    );
  }
}

五、定位动画提示

? ? ? ? 根据父元素的位置,定位动画起始位置,设置动画效果

页面文件

import 'package:flutter/material.dart';

import '../../component/layout.dart';
import 'animated.dart';
class TestToast extends StatefulWidget {
  const TestToast({Key? key}) : super(key: key);
  static const routeName = '/testtoast'; 
  @override
  State<TestToast> createState() => _TestToastState();
}

class _TestToastState extends State<TestToast> {
  final GlobalKey widgetKey = GlobalKey();

  void _onTapHandle() {
    Layout.showPosition(
      context: context,
      widgetKey: widgetKey, 
      builder: (context,size,offset){
        return const Animated();
      }
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          const SizedBox(height: 100,),
          Container(
            height: 200,
            width:200,
            key: widgetKey,
            color: Colors.blue,
            child: const Text('父节点'),
          ),
          TextButton(
            onPressed: _onTapHandle,
            child: const Text("动画")
          )
        ],
      )
    );
  }
}

定位文件layout.dart


import 'package:flutter/material.dart';
class Layout{

  static showPosition({
    required BuildContext context,
    required GlobalKey widgetKey,
    required Widget Function(BuildContext context,Size size,Offset offset) builder,
    Duration duration =const Duration(seconds: 2),
    Offset Function(Size size,Offset offset)? resetPosition
  }){
    RenderBox renderBox = widgetKey.currentContext!.findRenderObject()! as RenderBox;
    Size size = renderBox.paintBounds.size;
    Offset offset = renderBox.localToGlobal(Offset.zero);
    late Offset _offset = offset;
    if(resetPosition!=null){
      _offset =resetPosition(size,offset);
    }
    //创建一个OverlayEntry对象
    OverlayEntry overlayEntry = new OverlayEntry(builder: (context) {
    //外层使用Positioned进行定位,控制在Overlay中的位置
      return new Positioned(
          top:_offset.dy,
          left: _offset.dx,
          child:builder(context,size,offset)
        );
    });
    //往Overlay中插入插入OverlayEntry
    Overlay.of(context)!.insert(overlayEntry);
    //两秒后,移除Toast
    new Future.delayed(duration).then((value) {
      overlayEntry.remove();
    });
  }

}

动画文件animated.dart

import 'package:flutter/material.dart';
class Animated extends StatefulWidget {
  const Animated({ Key? key }) : super(key: key);

  @override
  State<Animated> createState() => _AnimatedState();
}

class _AnimatedState extends State<Animated> {
  late double _opacity = 0.0;
  late Matrix4 _transform = Matrix4.translationValues(0, 0, 0);

  @override
  void initState() {
    super.initState();
    Future.delayed(const Duration(microseconds: 0)).then((value) {
        setState(() {
          _opacity = _opacity == 1.0 ? 0.0 : 1.0;
          _transform = _opacity == 0.0
              ? Matrix4.translationValues(0, 0, 0)
              : Matrix4.translationValues(100, 0, 0);
        });
    });
  }

  @override
  Widget build(BuildContext context) {
    return  AnimatedContainer(
      duration: const Duration(milliseconds: 500),
      transform: _transform,
      child: AnimatedOpacity(
        opacity: _opacity,
        duration: const Duration(milliseconds: 500),
        child: const Text(
          "+1",
          style: TextStyle(
            color: Colors.red
          ),
        ),
      ),
    );
  }
}

效果

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-05-13 11:58:23  更:2022-05-13 11:59:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:48:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码