今天对flutter的容器布局又有了更深刻的了解,分别做了两个小案例,第一个是梯形布局,就像一个梯子一样。另外一个是关于阴影部分的。首先要明白flutter容器中的宽约束和紧约束。前者是指一个区间范围内,后者是指大和小必须要一样。后者会跟随父容器的大小改变,并且自己不能做控制。关于布局里面又一句非常核心的话:
向下传约束,向上传尺寸
这是效果图
梯形代码:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class DiagonalDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Diagonal(
children: [
FlutterLogo(size: 50,),
FlutterLogo(size: 60,),
FlutterLogo(size: 70,),
FlutterLogo(size: 80,),
FlutterLogo(size: 80,),
],
),
),
);
}
}
class Diagonal extends StatelessWidget{
List<Widget> children;
Diagonal({this.children});
@override
Widget build(BuildContext context) {
return CustomMultiChildLayout(
delegate: MyDelegateCase(children.length),
children: List.generate(
children.length,
(index){
return LayoutId(id: index, child: children[index]);
}),
);
}
}
class MyDelegateCase extends MultiChildLayoutDelegate{
int length;
var _size;
MyDelegateCase(this.length);
@override
void performLayout(Size size) {
//获取的父级容器的高度和宽度
print(size);
//定义在这里,每
double _x = 0;
double _y = 0;
for (int i = 0; i < length; i++) {
_size = layoutChild(
i,
//宽松约束
BoxConstraints.loose(size),
);
positionChild(i, Offset(_x,_y));
_x = _x + _size.width;
_y = _y + _size.height;
}
@override
bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate)=>true;
}
class MyDelegate extends MultiChildLayoutDelegate{
var size1,size2;
@override
void performLayout(Size size) {
if(hasChild(1)){
size1 = layoutChild(1, BoxConstraints(maxHeight: 200,minHeight: 0,maxWidth: 300,minWidth: 0));
positionChild(1, Offset(0.0,0.0));
}
if(hasChild(2)){
size2 = layoutChild(2, BoxConstraints(maxHeight: 300,minHeight: 0,maxWidth: 400,minWidth: 0));
positionChild(2, Offset(size1.width,size1.height));
}
}
@override
bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate)=>true;
//向下传递约束,向上传递尺寸
@override
Size getSize(BoxConstraints constraints) {
//调用父级约束
return super.getSize(constraints);
}
}
关于阴影部分和绘制溢出效果代码
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class MyRenderBoxDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: MyRenderBox(
distance: 10.0,
child: FlutterLogo(size: 300,),
),
),
);
}
}
class MyRenderBox extends SingleChildRenderObjectWidget {
double distance;
MyRenderBox({Widget child,this.distance}):super(child: child);
@override
RenderObject createRenderObject(BuildContext context) {
return RenderShadowBox(distance);
}
@override
void updateRenderObject(BuildContext context, covariant RenderShadowBox renderObject) {
renderObject.distance = distance;
}
}
class RenderShadowBox extends RenderProxyBox with DebugOverflowIndicatorMixin{
double distance;
RenderShadowBox(this.distance);
@override
void paint(PaintingContext context, Offset offset) {
context.paintChild(child, offset);
context.pushOpacity(offset, 127, (context, offset) {
context.paintChild(child, offset + Offset(distance,distance));
});
//限定高度
paintOverflowIndicator(context, offset, offset&size, Rect.fromLTWH(0, 0, 320, 300));
}
}
总结
这几天主要学的不是flutter,但是还是忍不住要去研究一下,可以这个会是引领下个编程时代的潮流