概要
一、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
),
),
),
);
}
}
效果
|