How can I layout widgets based on the size of the parent?

Let's say you have a parent widget that might have a variable size.

For example:

var container = new Container(
height: 200.0, // Imagine this might change
width: 200.0, // Imagine this might change
// Imagine content in this container will
// depend on the parent container
child: new Container(),
);

And maybe you want to have the child of the parent container render something different based on the size that it's given.

Think of responsive design breakpoints, if the width is over X use this layout, if the width is under X use that layout.

What's the best way to do this in Flutter?

111169 次浏览

您需要使用构建 并提供父部件的约束布局生成器小部件

The LayoutBuilder takes in a build() function which has the the standard BuildContext along with the 盒子约束 as parameters that can be used to help dynamically render widgets based on size.

让我们构建一个简单的小部件示例,如果父宽度大于200px,则呈现“ LARGE”,如果父宽度小于或等于此,则呈现“ SMALL”。

var container = new Container(
// Toggling width from 100 to 300 will change what is rendered
// in the child container
width: 100.0,
// width: 300.0
child: new LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
if(constraints.maxWidth > 200.0) {
return new Text('BIG');
} else {
return new Text('SMALL');
}
}
),
);

因此,我遇到了一个有趣的情况,我的父母的孩子根据内容(包含描述的文本)动态增加大小。这个父小部件以只读模式显示内容,但是这个解决方案也可以解决动态增加文本字段高度的其他问题。

I had a height variable and GlobalKey. In initState of widget I am using SchedulerBinding which runs it's addPostFrameCallback after layout is build.

GlobalKey 被分配给任何父部件,我们需要它的子部件的高度。

double height = 0.0;
GlobalKey _globalKey = GlobalKey();


@override
void initState() {
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
height = _globalKey.currentContext.size.height;
print('the new height is $height');
setState(() {});
});
super.initState();
}

and rest code looks like this

// this parent having dynamic height based on content
Container(
width: 100.0,
key: _globalKey,
child: Container(
width: 100.0,
child: Row(children: [  ///  you can have column as well or any other widget.
Container(child: ...),
Container(height: height,), ///this widget will take height from parent
],),
)
)

要根据父代码动态设置小部件大小,请使用以下代码:

Container(
color: Colors.red,
alignment: Alignment.center,
child: Wrap(children: <Widget>[


GestureDetector(
child: Text(
'Button',
style: TextStyle(
color: Color(0xff0079BF), fontSize:20),
),
onTap: () {




Navigator.pushReplacementNamed(context, '/signin');
},
),




Text(
'You have pushed the button this many times:',
style: TextStyle(fontSize: 50),
),


]),
)

我希望这个解决方案对你有用。

你可以试试 IntrinsicHeight 小部件:

Https://api.flutter.dev/flutter/widgets/intrinsicheight-class.html

对我来说,这是最简单的解决方案。但它似乎是昂贵的,所以你应该尽可能避免它

var container = Container(
height: 200.0, // Imagine this might change
width: 200.0, // Imagine this might change


child: IntrinsicHeight(
child: Container()),
);

将小部件放入一个容器中,并将其宽度和/或高度设置为 Double

例如:

 child: Container(
width: double.maxFinite,
)