一統天下 flutter - widget 容器類(只能有一個子): CustomSingleChildLayout - 自定義單組件佈局
示例如下:
lib\widget\container\custom_single_child_layout.dart
/*
* CustomSingleChildLayout - 自定義單組件佈局
*
* 注:約束是從上向下傳遞的,尺寸是從下向上傳遞的
*/
import 'package:flutter/material.dart';
import 'package:flutter_demo/helper.dart';
class CustomSingleChildLayoutDemo extends StatefulWidget {
const CustomSingleChildLayoutDemo({Key? key}) : super(key: key);
@override
_CustomSingleChildLayoutDemoState createState() => _CustomSingleChildLayoutDemoState();
}
class _CustomSingleChildLayoutDemoState extends State<CustomSingleChildLayoutDemo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("title"),),
backgroundColor: Colors.orange,
/// 自定義佈局
body: CustomSingleChildLayout(
/// 通過指定的 delegate 實現具體的佈局
delegate: _MySingleChildLayoutDelegate(),
/// 通過 LayoutId 指定需要佈局的組件的 id
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
);
}
}
class _MySingleChildLayoutDelegate extends SingleChildLayoutDelegate {
/// 用於根據 CustomSingleChildLayout 自己的約束,決定 CustomSingleChildLayout 的子的約束
/// constraints 爲 CustomSingleChildLayout 的父傳給 CustomSingleChildLayout 的約束
/// 返回值爲 CustomSingleChildLayout 傳給子的約束
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
log("getConstraintsForChild constraints:$constraints");
var childConstraints = BoxConstraints(minWidth: 0, minHeight: 0, maxWidth: 100, maxHeight: constraints.maxHeight);
return childConstraints;
}
/// 用於根據 CustomSingleChildLayout 自己的尺寸以及 CustomSingleChildLayout 的子的尺寸,決定 CustomSingleChildLayout 的子的位置
/// size 爲 CustomSingleChildLayout 的尺寸
/// childSize 爲 CustomSingleChildLayout 的子的尺寸
/// 返回值爲 CustomSingleChildLayout 的子的位置
@override
Offset getPositionForChild(Size size, Size childSize) {
log("getPositionForChild size:$size, childSize:$childSize");
var dx = (size.width - childSize.width) / 2;
var dy = (size.height - childSize.height) / 2;
return Offset(dx, dy);
}
/// 當 SingleChildLayoutDelegate 發生變化時,通過這裏決定是否需要重新佈局
@override
bool shouldRelayout(covariant SingleChildLayoutDelegate oldDelegate) {
return true;
}
/// constraints 爲 SingleChildLayoutDelegate 的父傳給 SingleChildLayoutDelegate 的約束
/// 返回值爲 SingleChildLayoutDelegate 根據約束決定的自己的尺寸
@override
Size getSize(BoxConstraints constraints) {
var size = super.getSize(constraints);
log('getSize constraints:$constraints, size:$size');
return size;
}
}