注意点
- FlexItem 需要父组件有是FlexList
- FlexItem 界面边界 一般是 关于机型的函数: 比如 * MediaQuery.of(context).size.height < 640 ? 220 : 240
- 对于需要变形的FlexItem,对应的 flexFlag 记得设置为true
- FlexItem flexFlag 为 ture时, children不能有Spacer()
说明
场景:
- 如果List界面边界比估计的内容最小边界大,则是正常的ListView列表。
- 如果List界面边界比估计的内容最小边界小,
- 对于Item 没有flexFlag为true, 同1。
- 对于Item flexFlag为true, 不去管开发者的设置,取最小值。[即尽量让内容塞到当前屏里]
对于item元素,布局的关注的是单个对象的占页面的尺寸
对于List列表,布局的关注的是全局的信息
可能会有Bug...
代码
- FlexList
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class FlexList extends StatelessWidget {
const FlexList(
{Key key,
@required this.minHigh,
this.maxHigh = double.infinity,
this.appBar,
this.backgroundColor,
this.children,
this.isCoverContent})
: super(key: key);
final double minHigh;
final double maxHigh;
final PreferredSizeWidget appBar;
final Color backgroundColor;
final List<Widget> children;
final bool isCoverContent;
@override
Widget build(BuildContext context) {
double contextHight = MediaQuery.of(context).size.height -
MediaQuery.of(context).viewPadding.top -
(appBar != null ? 0 : kToolbarHeight);
debugPrint(contextHight.toString());
return ListView(children: <Widget>[
Container(
height: min(max(contextHight, minHigh ?? 0), maxHigh) +
MediaQuery.of(context).viewInsets.bottom,
child: Scaffold(
appBar: appBar,
backgroundColor: backgroundColor ?? Colors.transparent,
body: ChangeNotifierProvider<FlexParent>(
builder: (context) =>
FlexParent(isCoverContent: isCoverContent == null ? contextHight > minHigh : isCoverContent),
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: children,
),
)),
))
]);
}
}
class FlexParent with ChangeNotifier {
bool isCoverContent;
FlexParent({this.isCoverContent});
}
- FlexItem
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'flex_list.dart';
class FlexItem extends StatelessWidget {
const FlexItem({
Key key,
@required this.windowHigh,
this.padding,
this.children,
this.flexFlag = false,
this.crossAxisAlignment = CrossAxisAlignment.center,
this.textDirection,
this.verticalDirection = VerticalDirection.down,
this.textBaseline,
}) : super(key: key);
final double windowHigh;
final EdgeInsets padding;
final List<Widget> children;
final bool flexFlag;
final CrossAxisAlignment crossAxisAlignment;
final TextDirection textDirection;
final VerticalDirection verticalDirection;
final TextBaseline textBaseline;
@override
Widget build(BuildContext context) {
return Consumer<FlexParent>(
builder: (_, model, __) {
bool minFlag = false;
if (model.isCoverContent == false) minFlag = flexFlag;
debugPrint('FlexItem:' +
windowHigh.toString() +
' ' +
minFlag.toString());
return Container(
height: minFlag ? null : windowHigh,
padding: padding ?? EdgeInsets.all(0),
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: children,
// options
crossAxisAlignment: crossAxisAlignment,
textDirection: textDirection,
verticalDirection: verticalDirection,
textBaseline: textBaseline,
),
);
},
// )
);
}
}