一个使用CustomSingleChildLayout和SingleChildLayoutDelegate自定义控件layout且带动画的例子。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomePage(title: 'Flutter Demo Home Page'),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key, required this.title});
final String title;
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
late AnimationController controller;
@override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
controller.addListener(() {
setState(() {});
});
controller.repeat(reverse: true);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Align(
alignment: Alignment.topLeft,
child: Container(
color: Colors.lightBlueAccent,
width: 400,
height: 200,
child: CustomSingleChildLayout(
delegate: MySingleDele(controller),
child: const ColoredBox(color: Colors.red),
),
),
),
);
}
}
// 自定义SingleChildLayoutDelegate
class MySingleDele extends SingleChildLayoutDelegate {
final Animation relayout;
MySingleDele(this.relayout) : super(relayout: relayout);
@override
bool shouldRelayout(covariant SingleChildLayoutDelegate oldDelegate) {
return false;
}
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
// 设置子控件的尺寸大小
return BoxConstraints.tight(const Size(10, 10));
}
@override
Offset getPositionForChild(Size size, Size childSize) {
// 设置子控件的位置
return Offset((size.width - childSize.width) * relayout.value,
(size.height - childSize.height) * relayout.value);
}
}