【问题标题】:Flutter: How to make ListView to occupy available parent heightFlutter:如何让 ListView 占据可用的父级高度
【发布时间】:2020-11-29 19:52:48
【问题描述】:

显示ListView 后出现错误。我想要实现的是“PlacesControls”小部件是固定大小的,其余部分应该占据下面的剩余空间。所以我用Expanded 包裹了我的ListView 来实现这一点,但现在我遇到了这个错误。

错误:The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type BoxParentData.

页面:

BlocProvider<PlacesBloc> buildBody(BuildContext context) {
    return BlocProvider(
      builder: (_) => sl<PlacesBloc>(),
      child: Center(
        child: Padding(
            padding: const EdgeInsets.all(10),
            child: Expanded(
              child: Column(
                children: <Widget>[
                  // Top view
                  SizedBox(height: 20),
                  PlacesControls(),
                  // Bottom view
                  BlocBuilder<PlacesBloc, PlacesState>(
                    builder: (context, state) {
                      if (state is Empty) {
                        return MessageDisplay(
                          message: 'Search places around you!',
                        );
                      } else if (state is Loading) {
                        return LoadingWidget();
                      } else if (state is Loaded) {
                        return PlacesDisplay(places: state.places);
                      } else if (state is Error) {
                        return MessageDisplay(
                          message: state.message,
                        );
                      }
                    },
                  ),
                ],
              ),
            )),
      ),
    );
  }

`PlacesDisplay - ListView':

class PlacesDisplay extends StatelessWidget {
  final List<Place> places;

  const PlacesDisplay({
    Key key,
    @required this.places,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Expanded(
          child: ListView.builder(
              itemCount: places.length,
              itemBuilder: (context, index) {
                return ListTile(title: Text(places[index].name));
              })),
    );
  }
}

这里是布局期望设计绿色小部件的高度应该是根据父窗口高度动态的(它的ListView也应该是可滚动的):

【问题讨论】:

  • 不应该只围绕地点显示展开吗? return Expanded(child: PlacesDisplay(places: state.places));
  • 嘿马丁,你也可以upvote 回答,我会很感激的。这对我也有帮助。谢谢:)我很高兴它为你解决了:)

标签: flutter flutter-layout


【解决方案1】:

需要更改:

  • 返回Expaned() 并包装你的PlacesDisplay
  • mainAxissize: MainAxisSize.min 应该在 Page Column 里面
  • 不要使用Expanded 包裹您的Padding。设备的Containerheightwidth 应该没问题

页面

BlocProvider<PlacesBloc> buildBody(BuildContext context) {
    return BlocProvider(
      builder: (_) => sl<PlacesBloc>(),
      child: Center(
        child: Container( // <---- changed
            height: MediaQuery.of(context).size:height, // <---- changed
            width: MediaQuery.of(context).of.width, // <---- changed
            padding: const EdgeInsets.all(10),
            child: Column(
                mainAxisSize: MainAxisSize.min, // <---- changed
                children: <Widget>[
                  // Top view
                  SizedBox(height: 20),
                  PlacesControls(),
                  // Bottom view
                  BlocBuilder<PlacesBloc, PlacesState>(
                    builder: (context, state) {
                      if (state is Empty) {
                        return MessageDisplay(
                          message: 'Search places around you!',
                        );
                      } else if (state is Loading) {
                        return LoadingWidget();
                      } else if (state is Loaded) {
                        return Expanded(
                           child: PlacesDisplay(places: state.places)   // <--- changed
                        );
                      } else if (state is Error) {
                        return MessageDisplay(
                          message: state.message,
                        );
                      }
                    },
                  ),
                ],
              ),
            ))
    );
  }

在您的PlacesDisplay 中,只需返回您的ListView.builder()

PlacesDisplay

class PlacesDisplay extends StatelessWidget {
  final List<Place> places;

  const PlacesDisplay({
    Key key,
    @required this.places,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(   // <--- changed
       itemCount: places.length,
       itemBuilder: (context, index) {
          return ListTile(title: Text(places[index].name));
       });
  }
}

【讨论】:

    【解决方案2】:

    错误是因为您使用了 Expanded 小部件来包装 Column。如果您希望列占据所有高度,则应使用mainAxisSize: MainAxisSize.max, 而不是用Expanded 包裹它。 Expanded 小部件只能在 RowColumnFlex 内使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-28
      • 2021-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      相关资源
      最近更新 更多