Home Articles

如何让黄色容器扩展并填充其紫色父母可用的其余空间

Asked
Viewed 1886 times
2

这是一个具体的例子,要求案例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

this shows the current output vs the desired output

------------------------- 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 Answers

  • 2

    您必须进行以下更改:

    1.-用SizedBox()替换ConstrainedBox()

    2.-用Expanded()替换最后一个Flexible() . 灵活适应容器的大小 . 通过删除容器子项来尝试它 .

    3.-最后切换绿色Container()和黄色Container() . 否则绿色的扩展 .

    这是脚手架的工作代码:

    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 SizedBox(
                width: 125.0, // Do your calculations based on isWidthMax
                height: double.infinity,
                //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 Expanded(
                        child: new Container(
                          color: Colors.amberAccent,
                          child: sheet,
                        ),
                      ),
                      new Container(
                        color: Colors.greenAccent,
                        child: (attachment != null) ? attachment : null,
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        );
      }
    

    这就是结果

    enter image description here

  • 1

    您需要将内部 Row 包装成 IntrinsicWidth 以强制执行它以根据其内容占用尽可能少的空间 .

    多亏了这一点,您现在可以将该内部行的子项包装到_1838623中,而不会出现异常 .

    enter image description here

    new Row(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        new Expanded(
          child: new Container(
            color: Colors.red,
          ),
        ),
        new ConstrainedBox(
          constraints: new BoxConstraints(minWidth: 100.0),
          child: new Container(
            color: Colors.purple,
            child: new IntrinsicWidth(
              child: new Row(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  new Container(
                    color: Colors.cyan,
                    child: new Icon(Icons.title),
                  ),
                  new Expanded(
                    child: new Container(
                        color: Colors.yellow,
                        alignment: Alignment.center,
                        child: new Icon(Icons.theaters)),
                  ),
                ],
              ),
            ),
          ),
        ),
      ],
    ),
    

Related