ListView 的 Flutter 动态高度

Bil*_*ill 12 flutter

我正在开发一个Flutter应用程序,我想动态调整 ListView 的高度。

我希望列表的最大高度为200. 如果高度超过这个,用户将不得不滚动到底部。如果高度低于200,它将只占用所需的空间。

应用预览:截图。如您所见Restaurants nearby,被推送到页面的最底部。我希望 ListView 的高度仅为 1/2200或更低,这样下面的内容就不会被推到底部。

这是我当前的代码:

@override
Widget build(BuildContext context) {
  return Container(
    padding: EdgeInsets.all(10.0),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Text(
          'Restaurants nearby',
          style: TextStyle(
            fontSize: 20.0,
            fontWeight: FontWeight.bold,
          ),
        ),
        Divider(),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              child: Text('Enter restaurant manually'),
              onPressed: () {
                print('Button pressed');
              },
            ),
          ],
        ),
        Flexible(
          child: ListView.builder(
            itemBuilder: (BuildContext context, int index) {
              return ListTile(
                leading: CircleAvatar(
                  backgroundColor: Colors.cyan,
                ),
                title: Text('Test restaurant'),
                subtitle: Text('80m'),
              );
            },
            itemCount: 15,
          ),
        ),
        Text(
          'Restaurants nearby',
          style: TextStyle(
            fontSize: 20.0,
            fontWeight: FontWeight.bold,
          ),
        ),
      ],
    ),
  );
}
Run Code Online (Sandbox Code Playgroud)

die*_*per 21

您正在使用Flexible小部件,这就是您ListView扩展的原因。您必须更改FlexibleConstrainedBox并添加shrinkWrap: true到您的ListView.

ConstrainedBox(
  constraints: BoxConstraints(maxHeight: 200, minHeight: 56.0),
  child: ListView.builder(
    shrinkWrap: true,
      itemBuilder: (BuildContext context, int index) {
        return ListTile(
          leading: CircleAvatar(
            backgroundColor: Colors.cyan,
          ),
          title: Text('Test restaurant'),
          subtitle: Text('80m'),
        );
      },
    itemCount: 15,
  ),
),
Run Code Online (Sandbox Code Playgroud)

更多信息在这里:https : //api.flutter.dev/flutter/widgets/ConstrainedBox-class.html

  • 在这种情况下,高度不是动态的。如果`ListView` 的高度小于`200`,那么`SizedBox` 仍将采用`200` 的高度。我不想要那个。我想根据列表的高度自动调整高度,但不超过`200`。如果它超过 `200`,则用户必须滚动才能到达 `ListView` 的底部。 (2认同)

小智 8

考虑将其包装ListView到此中

LimitedBox(
  maxHeight: 200,
  child: Column(
    mainAxisSize: MainAxisSize.min,
    children: [
      Flexible(
        child: ListView.builder(
          shrinkWrap: true,
          itemBuilder: (BuildContext context, int index) {
            return ListTile(
              leading: CircleAvatar(
                backgroundColor: Colors.cyan,
              ),
              title: Text('Test restaurant'),
              subtitle: Text('80m'),
            );
          },
          itemCount: _itemsCount,
        ),
      ),
    ]
  )
),
Run Code Online (Sandbox Code Playgroud)

注意:

  • shrinkWrapListView设置为true
  • mainAxisSizeColumn设置为MainAxisSize.min
  • maxHeightLimitedBox设置为200

一个完整的片段:

import 'package:flutter/material.dart';

class DebugWidget extends StatefulWidget {
  @override
  _DebugWidgetState createState() => _DebugWidgetState();
}
class _DebugWidgetState extends State<DebugWidget> {
  int _itemsCount = 1;

  @override
  Widget build(BuildContext context) {
    Widget child = Container(
      padding: EdgeInsets.all(10.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(
            'Restaurants nearby',
            style: TextStyle(
              fontSize: 20.0,
              fontWeight: FontWeight.bold,
            ),
          ),
          Divider(),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              RaisedButton(
                child: Text('Enter restaurant manually'),
                onPressed: () {
                  print('Button pressed');
                },
              ),
              RaisedButton(
                child: Text('+1'),
                onPressed: () {
                  setState(() {
                    _itemsCount += 1;
                  });
                },
              ),
              RaisedButton(
                child: Text('-1'),
                onPressed: () {
                  setState(() {
                    _itemsCount -= 1;
                  });
                },
              ),
            ],
          ),
          LimitedBox(
            maxHeight: 200,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Flexible(
                  child: ListView.builder(
                    shrinkWrap: true,
                    itemBuilder: (BuildContext context, int index) {
                      return ListTile(
                        leading: CircleAvatar(
                          backgroundColor: Colors.cyan,
                        ),
                        title: Text('Test restaurant'),
                        subtitle: Text('80m'),
                      );
                    },
                    itemCount: _itemsCount,
                  ),
                ),
              ]
            )
          ),
          Text(
            'Restaurants nearby',
            style: TextStyle(
              fontSize: 20.0,
              fontWeight: FontWeight.bold,
            ),
          ),
        ],
      ),
    );

    return Scaffold(
      body: child,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


And*_*sky 7

您可以使用LimitedBox

Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
    Text(...),
    Divider(),
    Row(...),
    LimitedBox(
      maxHeight: 200.0,
      child: ListView.builder(...),
    ),
    Text(...),
  ],
),
Run Code Online (Sandbox Code Playgroud)

传入约束无界时的推荐解决方案


Pay*_*edi 6

我找到了解决这个问题的办法。你应该用LimittedBox或ConstraintBox包装你的ListView,并给它们maxHeight并将ListView的shrinkWrap属性设置为true。解决方案是这样的。

LimitedBox(
          maxHeight: 200,
          child: ListView.builder(
            shrinkWrap: true,
            itemBuilder: (BuildContext context, int index) {
              return ListTile(
                leading: CircleAvatar(
                  backgroundColor: Colors.cyan,
                ),
                title: Text('Test restaurant'),
                subtitle: Text('80m'),
              );
            },
            itemCount: 15,
          ),
        ),
Run Code Online (Sandbox Code Playgroud)