这里是一个样例代码,可以实现一次性全屏 lerp 出一个 rect 的渐变色 Shader:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
AnimationController _controller;
Animation<Color> _colorTween;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..forward();
_colorTween = ColorTween(
begin: Colors.blue,
end: Colors.red,
).animate(_controller);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: AnimatedBuilder(
animation: _colorTween,
builder: (BuildContext context, Widget child) {
return ShaderMask(
shaderCallback: (Rect bounds) {
return LinearGradient(
colors: [_colorTween.value.withOpacity(0.3), _colorTween.value.withOpacity(0.6)],
tileMode: TileMode.mirror,
).createShader(bounds);
},
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.white,
),
child: SizedBox.expand(),
),
);
},
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
在这个例子中,我们创建了一个 AnimationController
和一个 ColorTween
,并把它们传给 AnimatedBuilder
。在 AnimatedBuilder
中,我们使用了 ShaderMask
来创建一个 Shader
,这个 Shader
是使用 LinearGradient
渐变生成的。最后,我们把 ShaderMask
作为背景的 DecoratedBox
放入了 SizedBox.expand()
中。
在运行时,我们启动了 AnimationController
并且让它向前运行。这将自动更新 ColorTween
中的插值,并且触发动画重绘。最终,我们将得到一个渐变色的背景作为屏幕的全屏背景。