Flutter ListView.builder() 小部件的交叉轴占据了整个屏幕高度

Posted

技术标签:

【中文标题】Flutter ListView.builder() 小部件的交叉轴占据了整个屏幕高度【英文标题】:Flutter ListView.builder() widget's cross Axis is taking up the entire Screen height 【发布时间】:2021-05-05 20:47:14 【问题描述】:

我在 Flutter 的 Container 中使用 ListView.builder(scrollDirection: Horizo​​ntal) 小部件。 ListView 的主轴占据了预期的整个屏幕宽度。我希望 ListView 的 crossAxis(垂直方向)占据 ListView 的 Item 高度(仅包裹内容),但它占据了整个屏幕高度。

我创建了 DartPard 来解释问题。我希望 ListView 占据项目高度而不是整个屏幕高度。 飞镖垫链接:DartPard which shows the issue I am facing

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
   @override
   Widget build(BuildContext context) 
     return MaterialApp(
          theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
          debugShowCheckedModeBanner: false,
          home: Scaffold(
              body: SafeArea(
              child: Container(
              color: Colors.white,
              child: ListView.builder(
                  itemCount: 10,
                  scrollDirection: Axis.horizontal,
              itemBuilder: (context, index) 
                  return Container(
                           color: Colors.red,
                           child: Text(
                             'Item $index', 
                             style: TextStyle(color: Colors.black),
                  ),  
              );
            ,
          ),
         ),
        ),
       ),
      );
     
    

一些可行的解决方法:

    使用RowWrap 代替ListView。 为 ListView 提供固定高度。

我知道上面列出的方法会奏效。但我只想使用 ListView 来实现这一点。

【问题讨论】:

你试过用mainAxisSize: MainAxisSize.min将你的列表视图包装在一个列中吗? @Stijn2210 没用 【参考方案1】:

您是否尝试在列表视图上使用shrinkWrap: true

【讨论】:

shrinkWrap 将沿主轴收缩 ListView。我已经要求十字轴了。【参考方案2】:

这个问题类似这样:Flutter: Minimum height on horizontal list view

经过一番挖掘,我意识到 ListView 可能不是您要查找的小部件。

在此之前,我展示了控制 ListView 高度的唯一方法是通过固定的高度设置,因为这是 ListView 的设计目的 - 显示预先格式化的项目列表。

如果您想拥有与孩子设置高度相同的功能,这意味着小部件仅包装内容,那么我建议使用带有 RowSingleChildScrollView (注意:一定要设置滚动方向:Axis.horizo​​ntal)

像这样:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SafeArea(
          child: Container(
              // height: 100, // no need to specify here
              color: Colors.white,
              child: SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  children: <Widget>[
                    Container(
                      height: 300,
                      width: 300,
                      color: Colors.amber[600],
                      child: const Center(child: Text('Entry A')),
                    ),
                    Container(
                      height: 100,
                      color: Colors.amber[500],
                      child: const Center(child: Text('Entry B')),
                    ),
                    Container(
                      height: 50,
                      width: 100,
                      color: Colors.amber[100],
                      child: const Center(child: Text('Entry C')),
                    ),
                    Container(
                      height: 300,
                      width: 300,
                      color: Colors.amber[600],
                      child: const Center(child: Text('Entry A')),
                    ),
                    Container(
                      height: 100,
                      color: Colors.amber[500],
                      child: const Center(child: Text('Entry B')),
                    ),
                    Container(
                      height: 50,
                      width: 100,
                      color: Colors.amber[100],
                      child: const Center(child: Text('Entry C')),
                    ),
                    Container(
                      height: 300,
                      width: 300,
                      color: Colors.amber[600],
                      child: const Center(child: Text('Entry A')),
                    ),
                    Container(
                      height: 100,
                      color: Colors.amber[500],
                      child: const Center(child: Text('Entry B')),
                    ),
                    Container(
                      height: 50,
                      width: 100,
                      color: Colors.amber[100],
                      child: const Center(child: Text('Entry C')),
                    ),
                    Container(
                      height: 300,
                      width: 300,
                      color: Colors.amber[600],
                      child: const Center(child: Text('Entry A')),
                    ),
                    Container(
                      height: 100,
                      color: Colors.amber[500],
                      child: const Center(child: Text('Entry B')),
                    ),
                    Container(
                      height: 50,
                      width: 100,
                      color: Colors.amber[100],
                      child: const Center(child: Text('Entry C')),
                    ),
                    Container(
                      height: 300,
                      width: 300,
                      color: Colors.amber[600],
                      child: const Center(child: Text('Entry A')),
                    ),
                    Container(
                      height: 100,
                      color: Colors.amber[500],
                      child: const Center(child: Text('Entry B')),
                    ),
                    Container(
                      height: 50,
                      width: 100,
                      color: Colors.amber[100],
                      child: const Center(child: Text('Entry C')),
                    ),
                  ],
                ),
              )),
        ),
      ),
    );
  

+++++++OP注释后添加+++++++

如果您想为动态列表使用构建器,您也可以随时定义自己的!

import 'dart:math';

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  var _randHeight = Random();

  List<int> someList = [
    1,
    2,
    3,
    4,
    5,
    7,
    8,
    9,
    10,
    11,
    12,
    13,
    14,
    15,
    16,
    17,
    18,
    19,
    20
  ];

  var randHeight = Random();
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SafeArea(
          child: Container(
              color: Colors.white,
              child: SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: _createChildren(),
                ),
              )),
        ),
      ),
    );
  

  List<Widget> _createChildren() 
    return List<Widget>.generate(someList.length, (int index) 
      return Container(
        color: Colors.red,
        width: 100,
        height: _randHeight.nextInt(300).toDouble(),
        child: Text(someList[index].toString(),
            style: TextStyle(color: Colors.black)),
      );
    );
  

【讨论】:

除了为 ListView 使用固定高度之外没有其他办法吗? 不,我相信 ListViews 要求每个对象具有相同的 CrossAxis 大小。我用我认为您正在寻找的内容更新了答案 是的,使用行将解决我的问题。但我需要使用 ListView.builder() 因为列表是动态的,我什至想对列表进行分页(超过 1000 个项目的项目) 也许您可以定义自己的构建器?检查更新的答案

以上是关于Flutter ListView.builder() 小部件的交叉轴占据了整个屏幕高度的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中添加 ListView.builder 的填充顶部?

Flutter - ListView.builder:初始滚动位置

Flutter:ListView.builder 创建列

Flutter - 另一个 Listview 中的 Listview.builder

Flutter:ListView.builder 中的自动垂直高度

Flutter 应用程序,ListView.builder 首次运行时出现错误。需要重启应用(ListView.builder 和 image_picker)