Макет Flutter: как разместить строку внутри Flex (или другой строки) во Flutter? Также с помощью виджета Stack

Мне нужно поместить 2 скомпонованных виджета в один Row:

Скомпонованный виджет называется boxText. Мне он нужен дважды, каждый внутри границы с двумя Texts и TextFormField, например:

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'

person abnerh69    schedule 16.11.2017    source источник


Ответы (4)


Оберните ОБА Container и TextFormField в виджет 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,
          ),),
        ],
      ),
    ));
person Shady Aziza    schedule 16.11.2017

Проблема в том, что ваш Контейнер полагается на своего родителя, чтобы определить его ширину. Поскольку у него нет родителя, он бесконечно широк.

Чтобы решить эту проблему, дайте ему родителя, который скажет своему потомку, как обрабатывать ширину. Это делает гибкий или расширенный. Expanded сообщает своему дочернему элементу, чтобы он был как можно большим (чтобы расширить), а Flexible говорит своему дочернему элементу, чтобы он был как можно меньше (чтобы сжаться).

Мне кажется, вам лучше всего подойдет Expanded:

Измените свой код:

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

to

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

Row и Column виджеты первого макета фиксированного размера. Виджеты фиксированного размера считаются негибкими, потому что они не могут изменять свой размер после размещения.

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(),
      ),
    );
  }
}
person Paresh Mangukiya    schedule 28.04.2021

person    schedule
comment
добавить расширенный будет в порядке - person WTree; 23.12.2019