为什么 Flexible widget 填充所有可用的 space 尽管它的内容更小?

Why Flexible widget filling all the available space despite its content being smaller?

我设计的布局分为两部分:-

1.Horizontal Lisview固定在顶部

2.Vertical 其余布局的滚动视图

我希望 Horizo​​ntal Lisview 只占用 space 覆盖其 content.That 所需的部分,这就是我将其放入灵活小部件的原因。 我希望 Vertical Scrollview 填充所有可用的剩余部分 space.That 这就是为什么我将它放在 Expandable 小部件中的原因。

我的布局是这样的:-

Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Flexible(
      
      child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Flexible(
              child: NotificationListener<ScrollEndNotification>(
                  child: ListView(
                    scrollDirection: Axis.horizontal,
                    controller: _scrollController,
                    children: moduleList
                        .map((module) => moduleTemplate(module))
                        .toList(),
                  ),
                  onNotification: (t) {
                    if (_scrollController.position.pixels != 0) {
                      setState(() {
                        isScrolledToEnd = true;
                      });
                    } else {
                      setState(() {
                        isScrolledToEnd = false;
                      });
                    }
                    // allow the notification to continue to be dispatched to further ancestors.
                    return true;
                  }),
            ),
         
          ]),
    ),
    Expanded(
      
      child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  ...
                ]),
            Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  ...
                ]),
                    ],
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    )
  ],
));

// 列表项

Widget moduleTemplate(module) {
    return Container(
        margin: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
           ...
          ],
        
      ),
    );
  }

当我使用 运行 代码时,我看到我的 Flexible 和 Expandable 小部件都占据了屏幕的一半,因此我在布局的第一部分看到很多空 space,其中仅包含水平列表视图。 我的期望是我的布局的第一部分只会占用 space 它需要显示其内容,因为它被放置在默认情况下 FIT 值为 Loose 的 Flexible 小部件内。 要解决这个问题,我必须指定 flex 值来解决这个问题,但根据屏幕尺寸,它可能会溢出 layout.Hence 的顶部我想解决这个问题而不使用 flex.Why 我的顶部布局占据了一半的屏幕和有没有更好的修复方法?

简而言之,我没有 flex 值的输出看起来像屏幕被平分为两部分..第一部分在顶部有水平列表视图,其余部分 space 是空的..第二部分有 SingleChildScrollView..我想将 SingleChildScrollView 立即底部对齐到列表视图,删除未占用的空白 space

我不确定为什么您的代码没有按预期工作,但这应该可以实现您想要的结果:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);
  Widget moduleTemplate(module) {
    return Container(
      margin: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Container(
            width: 100,
            height: 100,
            color: Colors.pink,
          )
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Demo"),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Row(
              children: List.generate(5, (index) => null)
                  .map((module) => moduleTemplate(module))
                  .toList(),
            ),
          ),
          Expanded(
            child: SingleChildScrollView(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Container(
                        width: 100,
                        height: 100,
                        color: Colors.blue,
                      )
                    ],
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Container(
                        width: 100,
                        height: 100,
                        color: Colors.red,
                      ),
                      Container(
                        width: 100,
                        height: 100,
                        color: Colors.red,
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

黑色容器是水平滚动视图,有5个粉色框,其余是垂直滚动视图。我不得不多次实施与此类似的方法,每次将 SingleChildScrollViewRow 结合使用都会获得更好的结果,而且效果很好。我确定有一种方法可以使 ListView 也能正常工作,但在这种情况下,似乎 ListView 可以毫无问题地替换为 SingleChildScrollView