Я пытаюсь создать простую страницу входа в свое приложение Flutter. Я успешно создал текстовые поля и кнопки входа / входа. Я хочу добавить горизонтальный ListView. Когда я запускаю код, мои элементы исчезают, если я делаю это без ListView, все снова в порядке. Как мне это сделать правильно?

вернуть новый MaterialApp (
        home: новый Scaffold (
          appBar: новый AppBar (
            title: новый текст ("Вход / Регистрация"),
          ),
          body: новый контейнер (
            ребенок: новый Центр (
              дочерний элемент: новый столбец (
              mainAxisAlignment: MainAxisAlignment.center,
                дети: <Виджет> [
                  новое текстовое поле (
                    украшение: новый InputDecoration (
                      hintText: "E M A I L A D D R E S S"
                    ),
                  ),
                  новый Padding (отступ: новый EdgeInsets.all (15.00)),
                  новое текстовое поле (obscureText: true,
                    украшение: новый InputDecoration (
                      hintText: "P A S S W O R D"
                    ),
                    ),
                  новый Padding (отступ: новый EdgeInsets.all (15.00)),
                  новое текстовое поле (украшение: новый InputDecoration (
                    hintText: "U S E R N A M E"
                  ),),
                  новый RaisedButton (onPressed: null,
                  ребенок: новый текст («ПОДПИСАТЬСЯ»),),
                  новый Padding (отступ: новый EdgeInsets.all (15.00)),
                  новый RaisedButton (onPressed: null,
                  ребенок: новый текст ("ВХОД"),),
                  новый Padding (отступ: новый EdgeInsets.all (15.00)),
                  новый ListView (scrollDirection: Axis.horizontal,
                  дети: <Виджет> [
                    новый RaisedButton (onPressed: null,
                    ребенок: новый текст ("Facebook"),),
                    новый Padding (отступ: новый EdgeInsets.all (5.00)),
                    новый RaisedButton (onPressed: null,
                    ребенок: новый текст ("Google"),)
                  ],)

                ],
              ),
            ),
            маржа: новый EdgeInsets.all (15.00),
          ),
        ),
      );

Ответы (16)

Вы можете проверить вывод консоли. Выводит ошибку:

Следующее утверждение было сгенерировано во время performResize (): Горизонтальному окну просмотра была присвоена неограниченная высота. Видовые экраны расширяются по поперечной оси, заполняя свой контейнер и ограничивая соответствие своих дочерних элементов их протяженность по поперечной оси. В этом случае горизонтальному окну просмотра было предоставлено неограниченное количество вертикальное пространство для расширения.

Вам нужно добавить ограничение высоты в ваш горизонтальный список. Например. упаковка в Контейнер с высотой:

Контейнер (
  высота: 44,0,
  дочерний элемент: ListView (
    scrollDirection: Axis.horizontal,
    дети: <Виджет> [
      RaisedButton (
        onPressed: нуль,
        ребенок: текст ("Facebook"),
      ),
      Padding (отступ: EdgeInsets.all (5.00)),
      RaisedButton (
        onPressed: нуль,
        ребенок: Текст ("Google"),
      )
    ],
  ),
)

На самом деле, когда вы читаете документы, ListView должен находиться внутри расширенного виджета, чтобы он мог работать.

  Widget build(BuildContext context) {
return Scaffold(
    body: Column(
  children: [
    Align(
      child: PayableWidget(),
    ),
    Expanded(
      child: _myListView(context),
    )
  ],
));

}

Как уже упоминалось выше, обернуть список с расширенным решением - это решение.

Но когда вы имеете дело с вложенными столбцами, вам также необходимо ограничить ListView определенной высотой (часто сталкивался с этой проблемой).

Если у кого-то есть другое решение, укажите в комментарии или добавьте ответ.

Пример

  SingleChildScrollView(
   child: Column(
     children: [
       Image(image: ),//<< any widgets added
       SizedBox(),
       Column(
         children: [
           Text('header'),  //<< any widgets added
            Expanded(child: 
            ListView.builder(
              //here your code
               scrollDirection: Axis.horizontal,
        itemCount: items.length,
        itemBuilder: (BuildContext context, int index) {
            return Container();
                   } 
         )
        ),
        Divider(),//<< any widgets added
         ],
       ),

     ],
   ), 
  );

Expanded Widget increases its size as much as it can with the space available Since ListView essentially has an infinite height it will cause an error.

 Column(
  children: [
    Flexible(
      child: ListView(...),
    )
  ],
)

Here we should use the Flexible widget as it will only take the space it required as Expanded take full screen even if there are not enough widgets to render on full screen.

Попробуйте использовать Slivers:

Container(
    child: CustomScrollView(
      slivers: [
        SliverList(
          delegate: SliverChildListDelegate(
            [
              HeaderWidget("Header 1"),
              HeaderWidget("Header 2"),
              HeaderWidget("Header 3"),
              HeaderWidget("Header 4"),
            ],
          ),
        ),
        SliverList(
          delegate: SliverChildListDelegate(
            [
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
              BodyWidget(Colors.green),
              BodyWidget(Colors.orange),
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
            ],
          ),
        ),
        SliverGrid(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          delegate: SliverChildListDelegate(
            [
              BodyWidget(Colors.blue),
              BodyWidget(Colors.green),
              BodyWidget(Colors.yellow),
              BodyWidget(Colors.orange),
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
            ],
          ),
        ),
      ],
    ),
  ),
)

Вот очень простой способ. Есть разные способы сделать это, например, вы можете получить его с помощью Expanded, Sizedbox или Container, и его следует использовать в соответствии с потребностями.

  1. Используйте Expanded: виджет, который расширяет дочерний элемент Row, Columnили Flex, чтобы дочерний элемент заполняет доступное пространство.

    Расширенный (
        дочерний элемент: ListView (scrollDirection: Axis.horizontal,
            дети: <Виджет> [
              OutlineButton (onPressed: нуль,
                  ребенок: Текст ("Facebook")),
              Padding (отступ: EdgeInsets.all (5.00)),
              OutlineButton (onPressed: нуль,
                  ребенок: Текст ("Google")),
              Padding (отступ: EdgeInsets.all (5.00)),
              OutlineButton (onPressed: нуль,
                  ребенок: Текст ("Твиттер"))
            ]),
      ),
    

Использование виджета Expanded делает дочерний элемент Row, Columnили Flex расширяется, чтобы заполнить доступное пространство вдоль главная ось (например, по горизонтали для строки или по вертикали для столбца).

  1. Используйте SizedBox: ящик с указанным размером.

    SizedBox (
        высота: 100,
        дочерний элемент: ListView (scrollDirection: Axis.horizontal,
            дети: <Виджет> [
              OutlineButton (
                  цвет: Цвета. белый,
                  onPressed: нуль,
                  ребенок: Текст ("Амазонка")
              ),
              Padding (отступ: EdgeInsets.all (5.00)),
              OutlineButton (onPressed: нуль,
                  ребенок: Текст ("Instagram")),
              Padding (отступ: EdgeInsets.all (5.00)),
              OutlineButton (onPressed: нуль,
                  ребенок: Текст ("SoundCloud"))
            ]),
     ),
    

Если задан дочерний элемент, этот виджет заставляет его дочерний элемент иметь определенную ширину и / или высоту (при условии, что значения разрешены родительским элементом этого виджета).

  1. Используйте Контейнер: удобный виджет, который сочетает в себе стандартные рисование, позиционированиеи размер виджеты.

     Контейнер (
        высота: 80,0,
        дочерний элемент: ListView (scrollDirection: Axis.horizontal,
            дети: <Виджет> [
              OutlineButton (onPressed: нуль,
                  ребенок: Текст ("Shopify")),
              Padding (отступ: EdgeInsets.all (5.00)),
              OutlineButton (onPressed: нуль,
                  ребенок: Текст ("Yahoo")),
              Padding (отступ: EdgeInsets.all (5.00)),
              OutlineButton (onPressed: нуль,
                  ребенок: Текст ("LinkedIn"))
            ]),
      ),
    

Результат для всех трех будет примерно таким

enter image description here

  Column(
    children: [
      Text('Leading text widget'),
      ListView(
        shrinkWrap: true,
        physics: NeverScrollableScrollPhysics(),
        children: [
          ListTile(
            leading: Icon(Icons.map),
            title: Text('Map'),
          ),
          ListTile(
            leading: Icon(Icons.photo_album),
            title: Text('Album'),
          ),
          ListTile(
            leading: Icon(Icons.phone),
            title: Text('Phone'),
          ),
        ],
      ),
      Text('More widget'),
    ],
  );

просто используйте

shrinkWrap: true,

physics: NeverScrollableScrollPhysics(),

свойства в listView

[Solution Preview] - [List Items are scrollable but heading is fixed]

enter image description here

I have very small & straight forward answer, see putting listview inside column will force column to expand infinitely, which is basically an error thing.

Now if you put physics: NeverScrollableScrollPhysics(), like others suggested, in listview then whats the point of having listview if you disable scrolling inside it..

There is an easy fix, frankly I landed on this by hit and trial. Let me give you small explanation after code.

Column(
      children: [
        Text(
          "All Bookings",
          style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600, color: Colors.brown[700]),
        ),
        Expanded(
          child: Container(
            margin: EdgeInsets.only(top: 24),
            child: ListView.builder(
              itemCount: 30,
              itemBuilder: (BuildContext context, int index) => ListTile(
                title: Text("List Item ${index + 1}"),
              ),
            ),
          ),
        ),
      ],
    )

I had requirement to have title inside Column as first element & then put a Listview so that user can have scrolling list. This is a generic kind of requirement. You can put this in Bottom Sheet or Modal too.

Code Explanation:

  1. I kept first child as heading inside Column ok (which i donot want to scroll away, i want it to be fixed)
  2. I have Expanded child inside column, which is like acquire all the "remaining space" in column.
  3. Inside that I kept container (Just to put some space between title & list view with margin) this is optional, you can remove container and it will still work.
  4. Now the Listview is well constrained and it won't try to stretch infinitely in column. As Expanded widget already constrained it.

Please correct me if I am wrong anywhere or if this code doesn't work (it works as of now without errors :)

У меня тоже такая проблема. Мое решение - использовать виджет Expanded, чтобы увеличить оставшееся пространство.

Column(
  children: [
    Expanded(
      child: horizontalList,
    )
  ],
);
return new MaterialApp(
    home: new Scaffold(
      appBar: new AppBar(
        title: new Text("Login / Signup"),
      ),
      body: new Container(
        child: new Center(
          child: ListView(
          //mainAxisAlignment: MainAxisAlignment.center,
          scrollDirection: Axis.vertical,
            children: [
              new TextField(
                decoration: new InputDecoration(
                  hintText: "E M A I L    A D D R E S S"
                ),
              ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new TextField(obscureText: true,
                decoration: new InputDecoration(
                  hintText: "P A S S W O R D"
                ),
                ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new TextField(decoration: new InputDecoration(
                hintText: "U S E R N A M E"
              ),),
              new RaisedButton(onPressed: null,
              child:  new Text("SIGNUP"),),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new RaisedButton(onPressed: null,
              child: new Text("LOGIN"),),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new ListView(scrollDirection: Axis.horizontal,
              children: [
                new RaisedButton(onPressed: null,
                child: new Text("Facebook"),),
                new Padding(padding: new EdgeInsets.all(5.00)),
                new RaisedButton(onPressed: null,
                child: new Text("Google"),)
              ],)

            ],
          ),
        ),
        margin: new EdgeInsets.all(15.00),
      ),
    ),
  );

У меня есть SingleChildScrollView в качестве родителя и один виджет Column, а затем виджет просмотра списка как последний дочерний элемент.

Добавление этих свойств в список сработало для меня.

  physics: NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  scrollDirection: Axis.vertical,

Вы можете использовать виджеты Flex и Flexible. например:

Flex(
direction: Axis.vertical,
children: [
    ... other widgets ...
    Flexible(
        flex: 1,
        child: ListView.builder(
        itemCount: ...,
        itemBuilder: (context, index) {
            ...
        },
        ),
    ),
],

);

В моем случае я использовал

  • singleChildScrollView
  • Колонка
  • Контейнер
  • FutureBuilder - Просмотр списка

, и я хотел прокрутить последнюю прокрутку со всем столбцом для этого добавьте

physics: NeverScrollableScrollPhysics(),

эта строка в вашем списке.

Вам нужно сделать 2 вещи:

  • перенос Столбец внутри SingleChildScrollView
  • добавить shrinkWrap: true и физика: NeverScrollableScrollPhysics () в ListView

Почему работает:

Как я понял, NeverScrollableScrollPhysics отключить прокрутку ListView. Итак, прокрутка работает с SingleChildScrollView. Если я ошибаюсь, прокомментируйте ниже.

SingleChildScrollView (
  дочерний элемент: Столбец (
    crossAxisAlignment: CrossAxisAlignment.start,
    дети: [
      Текст ("Фильтр"),
      ListView.separated (
        shrinkWrap: правда,
        физика: NeverScrollableScrollPhysics (),
        itemCount: rides.length,
        itemBuilder: (контекст BuildContext, int index) {
          # вернуть какой-нибудь виджет
        }
      ),

Причина ошибки:

Столбец расширяется до максимального размера в направлении главной оси (вертикальная ось), как и ListView.

Решения

Итак, вам нужно ограничить высоту ListView. Есть много способов сделать это, вы можете выбрать тот, который лучше всего соответствует вашим потребностям.


  1. Если вы хотите, чтобы ListView занимал все оставшееся пространство внутри Столбец, используйте Expanded.

    Столбец (
      дети: <Виджет> [
        Расширенный (
          дочерний: ListView (...),
        )
      ],
    )
    

  1. Если вы хотите ограничить свой ListView определенной высотой, вы можете использовать SizedBox.

    Столбец (
      дети: <Виджет> [
        SizedBox (
          height: 200, // ограничить высоту
          дочерний: ListView (),
        )
      ],
    )
    

  1. Если ваш ListView маленький, вы можете попробовать на нем свойство shrinkWrap.

    Столбец (
      дети: <Виджет> [
        Посмотреть список(
          shrinkWrap: true, // использовать
        )
      ],
    )
    

Также вы можете попробовать использовать CustomScrollView

CustomScrollView (
      контроллер: _scrollController,
      осколки:  [
        SliverList (
          делегат: SliverChildBuilderDelegate (
            (BuildContext context, int index) {
              окончательный порядок OrderModel = _orders [индекс];

              Контейнер возврата (
                маржа: const EdgeInsets.symmetric (
                  по вертикали: 8,
                ),
                дочерний: _buildOrderCard (порядок, размер, контекст),
              );
            },
            childCount: _orders.length,
          ),
        ),
        SliverToBoxAdapter (
          дочерний элемент: _buildPreloader (контекст),
        ),
      ],
    );

Совет: _buildPreloader return CircularProgressIndicator или Текст

В моем случае я хочу показать в ListView несколько виджетов. Использование Column мне не подходит, потому что виджеты вокруг ListView внутри Column всегда отображаются «вверху» на экране, например «абсолютная позиция»

Простите за плохой английский

2022 WebDevInsider