这是一个具体的例子,要求案例2和案例3来自其他帖子How to use the constraints and sizes of other widgets during the build phase
------------------------- BASIC HEIRARCHY ----------------------- -
主[FLEX]孩子1:红色(扩展)孩子2:紫色(非扩展,但它遵守其最小约束)[FLEX] ------孩子1:绿色(非扩展,按预期工作)--- ---孩子2:黄色(我希望它能填充紫色可用的剩余空间,但系统不会让我只使用扩展)
-
-
-
-
-
-
-
-
-
-
-
- -目标 - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
我希望黄色方框能够填满紫色方框内剩余的空间 .
注意:非常特定的小部件组合,不允许我将黄色容器包装在扩展的小部件中
-------------------------为什么我不能使用扩展-------------------- -----
如果我将黄色小部件包装成扩展它会引发错误...这就是为什么......
在那个特殊的情况下,我有2个容器在flex儿童1(主要)内:红色的一个正在扩展所以...儿童2(主要):紫色的一个试图收缩包装其子女并采取最少的空间尽可能但技术上它没有最大限制(只有最小限制,这就是为什么仍然有一些紫色可见)
紫色的孩子也是一个弯曲,有两个孩子,因为紫色的flex正在试图收缩包裹它的孩子,它会告诉它的孩子做同一个孩子1(紫色):绿色容器做到这一点,它很好,因为我想要要做到这一点,但是......孩子2(紫色):我希望黄色容器填充紫色用最小宽度参数创建的空间
问题是黄色容器紫色父母告诉它收缩包装它的孩子(如上所述),但是如果我将它包装在扩展的小部件中,你告诉黄色容器扩展或换句话说不收缩包装它的孩子..并且黄色容器可以收缩包裹而不收缩包裹它的孩子,所以你得到一个错误
所以...我需要知道紫色容器的计算宽度,然后计算绿色容器的计算宽度,然后我的黄色容器的宽度将是yellow.width = purple.width - green.width
------------------------- CODE OUTPUT ----------------------- -
this shows the output of the code below
------------------------- MAIN.DART ---------------------- ---
import 'package:flutter/material.dart';
import 'materialSheet.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
final appTitle = 'Material Sheets Demo';
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: ThemeData.dark(),
home: new MaterialSheet(
app: new Text("kill \n\n me plz"),
sheet: new Icon(Icons.keyboard),
attachment: new Icon(Icons.attachment),
position: sheetPosition.right,
placement: attachmentPlacement.inside,
sheetMin: 125.0,
),
);
}
}
------------------------- MATERIALSHEET.DART ---------------------- ---
import 'package:flutter/material.dart';
//-------------------------Enumerations-------------------------
enum sheetPosition { top, right, bottom, left }
enum sheetType { modal, persistent }
enum attachmentPlacement { inside, outside }
class MaterialSheet extends StatelessWidget {
//-------------------------Parameters-------------------------
final Widget app;
final Widget sheet;
final Widget attachment;
final sheetPosition position;
final sheetType type; //TODO add in the scrim behind the thing
final attachmentPlacement placement;
final double sheetMin; //TODO
final double sheetMax; //TODO
final double percentBeforeOpen; //TODO
final bool autoOpenIndicator; //TODO
final double percentBeforeClose; //TODO
final bool autoCloseIndicator; //TODO
final bool vertiScroll; //TODO
final bool horiScroll; //TODO
final bool swipeToOpen; //TODO
final bool swipeToClose; //TODO
MaterialSheet(
{@required this.app,
@required this.sheet,
this.attachment,
this.position: sheetPosition.bottom,
this.type: sheetType.modal,
this.placement: attachmentPlacement.inside,
this.sheetMin,
this.sheetMax,
this.percentBeforeOpen: .5,
this.autoOpenIndicator: true,
this.percentBeforeClose: .5,
this.autoCloseIndicator: true,
this.vertiScroll: false,
this.horiScroll: false,
this.swipeToOpen: true,
this.swipeToClose: true});
//-------------------------Helper Code-------------------------k
BoxConstraints _calcBoxConstraints(bool fullWidth) {
if (sheetMin == null && sheetMax == null)
return new BoxConstraints();
else {
if (sheetMin != null && sheetMax != null) {
if (fullWidth) //we only care for height
return new BoxConstraints(
minHeight: sheetMin,
maxHeight: sheetMax,
);
else //we only care for width
return new BoxConstraints(minWidth: sheetMin, maxWidth: sheetMax);
} else {
if (sheetMin != null) {
//we only have min
if (fullWidth) //we only care for height
return new BoxConstraints(minHeight: sheetMin);
else //we only care for width
return new BoxConstraints(minWidth: sheetMin);
} else {
//we only have max
if (fullWidth) //we only care for h`eight
return new BoxConstraints(maxHeight: sheetMax);
else //we only care for width
return new BoxConstraints(maxWidth: sheetMax);
}
}
}
}
//-------------------------Actual Code-------------------------
@override
Widget build(BuildContext context) {
bool isWidthMax =
(position == sheetPosition.bottom || position == sheetPosition.top);
//-----Create the Widgets and Initially calculate Sizes
print("before test");
Scaffold testScaff = theSheet(isWidthMax, context);
print("after test");
//-----Apply Size constraints as needed
Align testAl = new Align();
return new Stack(
children: <Widget>[
//---------------Contains your Application
new Scaffold(
backgroundColor: Colors.green,
body: app,
),
//---------------Contains the Sheet
theSheet(isWidthMax, context),
],
);
}
Scaffold theSheet(bool isWidthMax, BuildContext context) {
Scaffold generatedScaffold = genScaff(isWidthMax);
EdgeInsetsGeometry padCheck = (((generatedScaffold.body as Flex).children[0] as Flexible).child as Container).padding;
print("value " + padCheck.toString());
return generatedScaffold;
}
Scaffold genScaff(bool isWidthMax) {
return new Scaffold(
body: new Flex(
direction: (isWidthMax) ? Axis.vertical : Axis.horizontal,
//ONLY relevant if position is top or bottom
textDirection: (position == sheetPosition.right)
? TextDirection.ltr
: TextDirection.rtl,
//ONLY relevant if position is left or right
verticalDirection: (position == sheetPosition.top)
? VerticalDirection.up
: VerticalDirection.down,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Flexible(
fit: FlexFit.loose,
child: new Container(
padding: EdgeInsets.all(18.3),
color: Colors.red,
)),
new ConstrainedBox(
constraints: _calcBoxConstraints(isWidthMax),
child: new Container(
color: Colors.purple,
child: new Flex(
direction: (isWidthMax) ? Axis.vertical : Axis.horizontal,
//ONLY relevant if position is top or bottom
textDirection: (position == sheetPosition.right)
? (placement == attachmentPlacement.inside)
? TextDirection.rtl
: TextDirection.ltr
: (placement == attachmentPlacement.inside)
? TextDirection.ltr
: TextDirection.rtl,
//ONLY relevant if position is left or right
verticalDirection: (position == sheetPosition.top)
? (placement == attachmentPlacement.inside)
? VerticalDirection.down
: VerticalDirection.up
: (placement == attachmentPlacement.inside)
? VerticalDirection.up
: VerticalDirection.down,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Container(
color: Colors.amberAccent,
child: sheet,
),
new Flexible(
fit: FlexFit.loose,
child: new Container(
color: Colors.greenAccent,
child: (attachment != null) ? attachment : null,
),
),
],
),
),
),
],
),
);
}
}
2 回答
您需要将内部
Row
包装成IntrinsicWidth
以强制执行它以根据其内容占用尽可能少的空间 .多亏了这一点,您现在可以将该内部行的子项包装到_1838623中,而不会出现异常 .
您必须进行以下更改:
1.-用SizedBox()替换ConstrainedBox()
2.-用Expanded()替换最后一个Flexible() . 灵活适应容器的大小 . 通过删除容器子项来尝试它 .
3.-最后切换绿色Container()和黄色Container() . 否则绿色的扩展 .
这是脚手架的工作代码:
这就是结果