繁体   English   中英

Flutter 布局:如何在 Flutter 的 Flex(或另一行)中放置一行? 还使用 Stack 小部件

[英]Flutter Layout: How can I put a Row inside a Flex (or another Row) in Flutter? Also using Stack widget

我需要把2个组成部件在一个Row

组合的小部件名为“boxText”。 我需要它两次,每个都在一个带有两个Texts和一个TextFormField的 Border 中,例如:

Stack
  Image and others
  Form
    Row or Flex or Whatever:
    +------------------------------+    +------------------------------+
    | Text  Text TextFormField     |    | Text Text  TextFormField     |
    +------------------------------+    +------------------------------+

我的代码(和眼泪): 重要提示:仅在添加TextFormField时才会发生异常。

@override
Widget build(BuildContext context) {
// Composed Widget
 Widget boxText = new Container(
  decoration: new BoxDecoration(
    border: new Border.all(
      color: Colors.cyan[100],
      width: 3.0,
      style: BorderStyle.solid,
    ),
  ),
  margin: new EdgeInsets.all(5.0),
  padding: new EdgeInsets.all(8.0),
  child: new Row(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      new Text(
        'Text',
        style: null,
      ),
      new Text(
        'Text',
        style: null,
      ),
      new TextFormField(
        decoration: const InputDecoration(
          hintText: '',
          labelText: 'label',
        ),
        obscureText: true,
      ),
    ],
  ),
);

return new Scaffold(
  key: _scaffoldKey,
  body: new Stack(
    alignment: AlignmentDirectional.topStart,
    textDirection: TextDirection.ltr,
    fit: StackFit.loose,
    overflow: Overflow.clip,
    children: <Widget>[

      new Container(
        color: Colors.red[200],
        margin: new EdgeInsets.only(
          left: MediaQuery.of(context).size.width * 0.05,
          right: MediaQuery.of(context).size.width * 0.05,
          top: MediaQuery.of(context).size.height * 0.4,
          bottom: MediaQuery.of(context).size.height * 0.1,
        ),
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: new Form(
          key: _formKey,
          child: new ListView(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            children: <Widget>[
              new Flex(
                direction: Axis.horizontal,
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  boxText,
                  boxText,
                ],
              ),
            ],
          ),
        ),
      ),
    ],
  ),
    );
  }

如果可能的话,如何在没有以下情况下使这个小部件工作:

══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞══

The following assertion was thrown during performLayout():

An InputDecorator, which is typically created by a TextField, cannot 
have an unbounded width.

This happens when the parent widget does not provide a finite width 
constraint. For example, if the InputDecorator is contained by a Row, 
then its width must be constrained. An Expanded widget or a SizedBox 
can be used to constrain the width of the InputDecorator or the 
TextField that contains it.

'package:flutter/src/material/input_decorator.dart':

Failed assertion: line 945 pos 7: 'layoutConstraints.maxWidth < 
double.infinity'

将您的ContainerTextFormField包裹在一个Flexible小部件中。

在此处输入图片说明

Widget boxText = new Flexible(child: new Container(
      decoration: new BoxDecoration(
        border: new Border.all(
          color: Colors.cyan[100],
          width: 3.0,
          style: BorderStyle.solid,
        ),
      ),
      margin: new EdgeInsets.all(5.0),
      padding: new EdgeInsets.all(8.0),
      child: new Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[

          new Text(
            'Text',
            style: null,
          ),
          new Text(
            'Text',
            style: null,
          ),
          new Flexible (child: new TextFormField(
            decoration: const InputDecoration(
              hintText: '',
              labelText: 'label',
            ),
            obscureText: true,
          ),),
        ],
      ),
    ));

问题是您的 Container 依赖其父级来决定其宽度。 因为它没有父级,所以它是无限宽的。

为了解决这个问题,给它一个告诉它的孩子如何处理宽度的父级。 一个灵活的或扩展的。 Expanded 告诉它的孩子尽可能大(扩展),Flexible 告诉它的孩子尽可能小(缩小)。

在我看来,Expanded 是您最好的选择:

更改您的代码:

// Composed Widget
Widget boxText = new Container(
  decoration: new BoxDecoration(
  // all your other code here
);

// Composed Widget
Widget boxText = Expanded(   // <-- Add this Expanded widget
  child: new Container(
    decoration: new BoxDecoration(
    // all your other code here
  ),
);

固定大小的RowColumn优先布局小部件。 固定大小的小部件被认为是不灵活的,因为它们在布局后无法自行调整大小。

flex在确定每个 Flexible 小部件接收的总剩余空间的比例之前,将自身与其他flex属性进行比较。

flex属性相互比较时,它们的 flex 值之间的比率决定了每个灵活小部件接收的总剩余空间的比例。

remainingSpace * (flex / totalOfAllFlexValues)

在这个例子中, flex值的总和 (2) 决定了两个Flexible小部件获得总剩余空间的一半。 BlueBox小部件(或固定大小的小部件)保持相同的大小。

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        BlueBox(),
        Flexible(
          fit: FlexFit.tight,
          flex: 1,
          child: BlueBox(),
        ),
        Flexible(
          fit: FlexFit.tight,
          flex: 1,
          child: BlueBox(),
        ),
      ],
    );
  }
}

class BlueBox extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 50,
      height: 50,
      decoration: BoxDecoration(
        color: Colors.blue,
        border: Border.all(),
      ),
    );
  }
}
         child: Row(
                children: <Widget>[
                  Expanded(
                    child: TextField(

                      decoration: InputDecoration(hintText: "text"),
                    ),
                  ),
                  Text("unit"),
                ],
              )),

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM