[英]Flutter Custom Animated Icon
我希望制作一個可以從列表中添加和刪除的項目。
我正在尋找的是擁有 + 圖標和 - 圖標,並在這兩個圖標之間設置動畫,以獲得干凈流暢的外觀。
我有以下代碼
Container(
padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
child: AnimatedIcon(
icon: AnimatedIcons.home_menu,
progress: _animationController,
color: Colors.white,
))
和
void _handleOnPressed() {
setState(() {
isPlaying = !isPlaying;
isPlaying
? _animationController.forward()
: _animationController.reverse();
});
}
這對於 flutter 中的內置動畫圖標來說很好。
我希望使用 + 和 - 圖標,但外觀相同。
有沒有辦法做到這一點?
你很幸運,我的朋友! Flutter 已經為您提供了 AnimatedIcon()
現在用 Flare 為您的圖標設置動畫。 Jeff Delaney 為此做了一個很好的教程。
https://fireship.io/lessons/animated-navigation-flutter-flare/
class _CreatePackageViewState extends State<CreatePackageView>
with SingleTickerProviderStateMixin {
bool expanded = true;
AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 400),
reverseDuration: Duration(milliseconds: 400),
);
}
IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_close,
progress: controller,
semanticLabel: 'Show menu',
),
onPressed: () {
setState(() {
expanded ? controller.forward() : controller.reverse();
expanded = !expanded;
});
}),
}
自定義動畫需要三樣東西
下面的簡單示例
import 'package:flutter/material.dart';
class AnimationsPractice extends StatefulWidget {
@override
_AnimationsPracticeState createState() => _AnimationsPracticeState();
}
class _AnimationsPracticeState extends State<AnimationsPractice> with SingleTickerProviderStateMixin {
AnimationController controller;
Animation animation;
@override
void initState() {
super.initState();
controller = AnimationController(
duration: Duration(milliseconds: 500),
vsync: this);
animation = ColorTween(begin: Colors.purple, end: Colors.red[700]).animate(controller);
controller.forward();
animation.addStatusListener((status) {
if(status == AnimationStatus.completed){
controller.reverse(from: 1.0);
print(animation.value);
}
else if(status == AnimationStatus.dismissed){
controller.forward();
}
});
controller.addListener(() {
setState(() {
});
print(controller.value);
});
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.yellow,
appBar: AppBar(
title: Text('Heart Beat'),
),
body: Center(
child: Icon(
Icons.favorite,
size: animation.value * 100,
),
),
);
}
}
使用 animated_icon_button package https://pub.dev/packages/animated_icon_button/install
我知道它不如AnimatedIcon漂亮,但您實際上可以通過幾行代碼使用您選擇的任何 2 個圖標獲得非常相似的過渡:
IconButton(
icon: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
transitionBuilder: (child, anim) => RotationTransition(
turns: child.key == ValueKey('icon1')
? Tween<double>(begin: 1, end: 0.75).animate(anim)
: Tween<double>(begin: 0.75, end: 1).animate(anim),
child: FadeTransition(opacity: anim, child: child),
),
child: _currIndex == 0
? Icon(Icons.close, key: const ValueKey('icon1'))
: Icon(
Icons.arrow_back,
key: const ValueKey('icon2'),
)),
onPressed: () {
setState(() {
_currIndex = _currIndex == 0 ? 1 : 0;
});
},
);
或者您可以使用ScaleTransition
代替FadeTransition
,並獲得更相似的 animation:
IconButton(
icon: AnimatedSwitcher(
duration: const Duration(milliseconds: 350),
transitionBuilder: (child, anim) => RotationTransition(
turns: child.key == ValueKey('icon1')
? Tween<double>(begin: 1, end: 0.75).animate(anim)
: Tween<double>(begin: 0.75, end: 1).animate(anim),
child: ScaleTransition(scale: anim, child: child),
),
child: _currIndex == 0
? Icon(Icons.close, key: const ValueKey('icon1'))
: Icon(
Icons.arrow_back,
key: const ValueKey('icon2'),
)),
onPressed: () {
setState(() {
_currIndex = _currIndex == 0 ? 1 : 0;
});
},
)
使用這種方法,您可以使用任何您想要的圖標,並且不需要創建單獨的AnimationController
來控制過渡,這與AnimatedIcon不同
看起來 Flutter 團隊使用名為 vitool 的命令行工具將 SVG 轉換為可用作動畫圖標的路徑。 如果你有一個相對簡單的動畫 SVG,你可以嘗試在這個存儲庫的 bin 文件夾中運行 main.dart 命令行工具:https://github.com/flutter/flutter/tree/master/dev/tools/vitool 。 我還沒有嘗試過,但如果我發現任何問題,我會嘗試並報告。 output 應如下所示:
const _AnimatedIconData _$menu_arrow = _AnimatedIconData(
Size(48.0, 48.0),
<_PathFrames>[
_PathFrames(
opacities: <double>[
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
(...)
您可以簡單地使用animate_icons 2.0.0
package 為兩個圖標設置動畫
AnimateIcons(
startIcon: Icons.add_circle,
endIcon: Icons.add_circle_outline,
size: 100.0,
controller: controller,
// add this tooltip for the start icon
startTooltip: 'Icons.add_circle',
// add this tooltip for the end icon
endTooltip: 'Icons.add_circle_outline',
size: 60.0,
onStartIconPress: () {
print("Clicked on Add Icon");
return true;
},
onEndIconPress: () {
print("Clicked on Close Icon");
return true;
},
duration: Duration(milliseconds: 500),
startIconColor: Colors.deepPurple,
endIconColor: Colors.deepOrange,
clockwise: false,
),
https://pub.dev/packages/animate_icons
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.