根据另一个小部件的位置/大小定位/调整小部件的大小

时间:2017-09-01 00:37:02

标签: dart flutter

我曾经在Flutter面对过一段相当大的墙。 动画或构建小部件,取决于其他小部件以获取其大小/位置。

一些可能是我最糟糕的噩梦的例子: 动态抓取小部件彼此相邻。 在CSS中我们有这个:



.root {
    display: flex;
    background: grey;
    padding: 4px;
}
.root > div {
  background: lightgrey;
  margin-right: 5px;
  padding: 5px;
}

<div class="root">
    <div>
         dynamic height
         <br/>
         dynamic width
         <br/>
         fat
         <br/>
         super fat
    </div>
    <div>
         dynamic width
         <br/>
         dynamic height
    </div>
</div>
&#13;
&#13;
&#13;

  • 父级占据整个宽度(不重要)。
  • 父母占据最大孩子的身高。
  • 身高较小的孩子伸展以适合父母
  • 孩子们彼此相邻定位

在颤抖中,我认为我们不能同时获得所有4分。

现在如果我们有2个这样的列表和一个动画,其中一个元素从一个列表转到另一个列表怎么办? 示例

enter image description here enter image description here

另一个例子。如果我们想让SlideTransition与另一个没有共同点的小部件垂直对齐,该怎么办? 像这样:

enter image description here

这些是完全随机的例子。我不需要重现完全相同的东西。 这里真正的问题是:是否有泛型方法来做类似的事情(获取屏幕尺寸/位置)?某些特定于此用例并且以后可以轻松维护的内容?

2 个答案:

答案 0 :(得分:5)

要回答原始布局问题,您可以使用IntrinsicHeight窗口小部件和CrossAxisAlignment.stretch完成此布局。它看起来像这样:

screenshot

以下是代码:

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Padding(
        padding: new EdgeInsets.all(10.0),
        child: new IntrinsicHeight(
          child: new Container(
            color: Colors.grey,
            padding: new EdgeInsets.all(4.0),
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                new Container(
                  padding: new EdgeInsets.all(5.0),
                  margin: new EdgeInsets.only(right: 5.0),
                  color: Colors.grey[200],
                  child: new Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      new Text('dynamic height'),
                      new Text('dynamic width'),
                      new Text('fat'),
                      new Text('super fat'),
                    ],
                  ),
                ),
                new Container(
                  padding: new EdgeInsets.all(5.0),
                  color: Colors.grey[200],
                  child: new Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      new Text('dynamic width'),
                      new Text('dynamic height'),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

为了实现更高级的动画示例,我建议使用CustomMultiChildLayout来定位框。有关使用此类的高级动画示例,请参阅图库的animation demo

screenshot

答案 1 :(得分:-1)

  • 父母取最大孩子的身高

您可以在行或列中使用 MainAxisSize.min,它用作父小部件的包装。

body: new Container(

 color: Colors.yellowAccent,

 child: new Row(

 mainAxisSize: MainAxisSize.min,

 children: [...],

 ),

)
  • 身高较小的孩子可以伸展以适应父母

FractionallySizedBox 是一个小部件(容器),根据它的 widthFactor 和 heightFactor,将设置所有子小部件。您可以将其视为一种比例值。因此,如果我们想要一个容器在水平和垂直方向上占用一半的可用空间,我们将执行以下操作:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FractionallySizedBox"),
      ),
      body: FractionallySizedBox(
        widthFactor: 0.5,
        heightFactor: 0.5,
        child: Container(
          // this container won't be larger than
          // half of its parent size
        ),
      ),
    );
  }
  • 孩子们紧挨着放置

当您希望将子项彼此相邻放置时,每个 Flutter 布局都使用行和列。

Row(
    children: [
          YourWidget(),
          YourWidget(),
          YourWidget(),
      ]
 )