列内的 Flutter Listview 未占用全高

Flutter Listview inside column not taking full height

以上一项为要求。实际上要求是第一个小部件(具有下面列表视图的垂直列表 header 应该全高)意味着列表视图是否有 18 个项目。它应该显示 18 个项目。然后在它下面应该显示水平滚动。

我尝试了我的方法,但由于列列表视图采用与其他元素相同的高度,因此它没有完全显示所有项目。它占用屏幕高度的一半,用户需要在该高度滚动。

需要你帮忙整理一下。由于第一个列表视图应占据全高,而第二个小部件应低于该高度。

请看下面的代码。

import 'dart:math';

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "Flutter test",
          style: TextStyle(color: Colors.black),
        ),
        elevation: 5,
        backgroundColor: Colors.white,
      ),
      body: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          ListHeader("Vertical List Header"),
          VerticalList(),
          ListHeader("Horizontal List Header"),
          HorizontalList(),
          ListHeader("Vertical List Header"),
          VerticalList(),
          ScrollUp()
        ],
      ),
    );
  }
}

class ScrollUp extends StatelessWidget {
  const ScrollUp({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return InkWell(
      child: Container(
        alignment: Alignment.bottomCenter,
        width: double.infinity,
        height: 50,
        child: Center(
          child: Text(
            "Click to scroll up",
            style: TextStyle(
              fontSize: 18,
            ),
          ),
        ),
      ),
    );
  }
}

class ListHeader extends StatelessWidget {
  final String title;
  const ListHeader(String title) : title = title;

  @override
  Widget build(BuildContext context) {
    return Text(
      title,
      style: TextStyle(fontSize: 18),
    );
  }
}

class HorizontalList extends StatelessWidget {
  const HorizontalList({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: ListView.builder(
          shrinkWrap: true,
          scrollDirection: Axis.horizontal,
          itemCount: 30,
          itemBuilder: (BuildContext context, int index) => Container(
                margin:
                    const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
                width: 30,
                height: 20,
                color: Colors.grey,
              )),
    );
  }
}

class VerticalList extends StatelessWidget {
  const VerticalList({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        itemBuilder: (ctx, int) {
          return Container(
            margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
            width: double.infinity,
            height: 50,
            color: Colors.primaries[Random().nextInt(Colors.primaries.length)],
          );
        },
        itemCount: 8,
      ),
    );
  }
}

这是我对同类问题的解决方案。

import 'package:flutter/material.dart';

class MealDetailsScreen extends StatelessWidget {
  Widget buildSectionTitle(BuildContext context, String title) {
    return Container(
      margin: EdgeInsets.symmetric(vertical: 10),
      child: Text(
        title,
        style: Theme.of(context).textTheme.bodyText1,
      ),
    );
  }

  Widget buildContainer({Widget child}) {
    return Container(
      decoration: BoxDecoration(
          color: Colors.white,
          border: Border.all(color: Colors.grey),
          borderRadius: BorderRadius.circular(10)),
      margin: EdgeInsets.all(10),
      padding: EdgeInsets.all(10),
      height: 300,
      width: 300,
      child: child,
    );
  }

  @override
  Widget build(BuildContext context) {
    final mealId = ModalRoute.of(context).settings.arguments;
    final selectedMeal =
        DUMMY_MEALS.firstWhere((element) => element.id == mealId);
    return Scaffold(
      appBar: AppBar(
        title: Text('${selectedMeal.title}'),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Container(
              height: 300,
              width: double.infinity,
              child: Image.network(
                selectedMeal.imageUrl,
                fit: BoxFit.cover,
              ),
            ),
            buildSectionTitle(context, 'Ingredients'),
            buildContainer(
              child: ListView.builder(
                itemBuilder: (ctx, index) => Card(
                  color: Theme.of(context).accentColor,
                  child: Padding(
                    padding:
                        const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
                    child: Text(selectedMeal.ingredients[index]),
                  ),
                ),
                itemCount: selectedMeal.ingredients.length,
              ),
            ),
            buildSectionTitle(context, 'Steps'),
            buildContainer(
              child: ListView.builder(
                itemBuilder: (ctx, index) => Column(
                  children: [
                    ListTile(
                      leading: CircleAvatar(
                        child: Text('# ${(index + 1)}'),
                      ),
                      title: Text(selectedMeal.steps[index]),
                    ),
                    Divider(),
                  ],
                ),
                itemCount: selectedMeal.steps.length,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Column 小部件更改为 ListView 小部件。

并将 shrinkWrap: true 添加到其子项 ListView's'

删除两个 ListView.Builder

上的 Expanded 小部件

横向 ListView.Builder 必须有固定高度 ( Link )

physics: NeverScrollableScrollPhysics()添加到垂直ListView.Builder

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return  Scaffold(
        appBar: AppBar(
          title: Text(
            "Flutter test",
            style: TextStyle(color: Colors.black),
          ),
          elevation: 5,
          backgroundColor: Colors.white,
        ),
        body: ListView(
          children: [
            ListHeader("Vertical List Header"),
            VerticalList(),
            ListHeader("Horizontal List Header"),
            HorizontalList(),
            ListHeader("Vertical List Header"),
            VerticalList(),
            ScrollUp()
          ],
        ),
      );
    
  }
}

class ScrollUp extends StatelessWidget {
  const ScrollUp({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return InkWell(
      child: Container(
        alignment: Alignment.bottomCenter,
        width: double.infinity,
        height: 50,
        child: Center(
          child: Text(
            "Click to scroll up",
            style: TextStyle(
              fontSize: 18,
            ),
          ),
        ),
      ),
    );
  }
}

class ListHeader extends StatelessWidget {
  final String title;
  const ListHeader(String title) : title = title;

  @override
  Widget build(BuildContext context) {
    return Text(
      title,
      style: TextStyle(fontSize: 18),
    );
  }
}

class HorizontalList extends StatelessWidget {
  const HorizontalList({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 400,
      child: ListView.builder(
          shrinkWrap: true,
          scrollDirection: Axis.horizontal,
          itemCount: 30,
          itemBuilder: (BuildContext context, int index) => Container(
                margin:
                    const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
                width: 30,
                height: 20,
                color: Colors.grey,
              )),
    );
  }
}

class VerticalList extends StatelessWidget {
  const VerticalList({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      physics: NeverScrollableScrollPhysics(),
      shrinkWrap: true,
      itemBuilder: (ctx, int) {
        return Container(
          margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
          width: double.infinity,
          height: 50,
          color: Colors.primaries[Random().nextInt(Colors.primaries.length)],
        );
      },
      itemCount: 8,
    );
  }
}