flutter - 有没有办法在列中使用 ListView.Builder 而无需收缩包装?

标签 flutter flutter-sliver

我正在尝试将 ListView.builder 放置在与 SliverAppBar 同等的 Column 中。因此,我需要利用 CustomScrollview 和 SliverToBoxAdapter,以便 Column 可以驻留在 CustomScrollView 内。

只要我将收缩包装设置为 true,这一切都可以正常工作。

但是,出于性能原因,我不想使用收缩包装(根据官方文档,这是非常昂贵的,并且否定了 ListView.Builder 延迟加载列表项的性能优势)。

错误是:“RenderFlex 子项具有非零弯曲,但传入的高度约束不受限制”。这是因为 Column 的高度无限。

我希望不必对列的大小进行硬编码,因为这将是一个响应式/自适应脚手架。

我的代码如下 - 我的问题是,有没有人能够使用带有 ListView.Builder 的 Column 作为子项,而不使用将收缩包装设置为 true 且无需对高度进行硬编码?

import 'package:flutter/material.dart';

class TestScaffold extends StatelessWidget {
  const TestScaffold({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueGrey[100],
      body: CustomScrollView(
        slivers: [
          SliverToBoxAdapter(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              mainAxisSize: MainAxisSize.min,
              children: [
                Expanded(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Text('Title 1'),
                      Expanded(
                        child: ListView.builder(
                          //shrinkWrap: true,
                          itemCount: 3,
                          itemBuilder: (context, index) {
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Container(
                                height: 100,
                                width: 100,
                                color: Colors.red,
                              ),
                            );
                          },
                        ),
                      ),
                    ],
                  ),
                ),
                const SizedBox(
                  width: 10,
                ),
                Expanded(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Text('Title 2'),
                      Expanded(
                        child: ListView.builder(
                          //shrinkWrap: true,
                          itemCount: 3,
                          itemBuilder: (context, index) {
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Container(
                                height: 100,
                                width: 100,
                                color: Colors.green,
                              ),
                            );
                          },
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}

最佳答案

当内部小部件使用 Expanded 时,您可以在 Row 上使用 SliverFillRemaining

class TestScaffold extends StatelessWidget {
  const TestScaffold({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueGrey[100],
      body: CustomScrollView(
        slivers: [
          SliverFillRemaining( //this
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              mainAxisSize: MainAxisSize.min,
              children: [
                Expanded(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Text('Title 1'),
                      Expanded(
                        child: ListView.builder(
                          //shrinkWrap: true,
                          itemCount: 3,
                          itemBuilder: (context, index) {
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Container(
                                height: 100,
                                width: 100,
                                color: Colors.red,
                              ),
                            );
                          },
                        ),
                      ),
                    ],
                  ),
                ),
                const SizedBox(
                  width: 10,
                ),
                Expanded(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Text('Title 2'),
                      Expanded(
                        child: ListView.builder(
                          //shrinkWrap: true,
                          itemCount: 3,
                          itemBuilder: (context, index) {
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Container(
                                height: 100,
                                width: 100,
                                color: Colors.green,
                              ),
                            );
                          },
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}

我想你也会喜欢使用SliverPersistentHeader针对您的情况。

关于flutter - 有没有办法在列中使用 ListView.Builder 而无需收缩包装?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75913500/

相关文章:

android - 当新版本上传到 appstore/playstore 时,如何使用 flutter 以编程方式更新 android/ios 应用程序

Flutter 如何使AppBar条子标题垂直居中?

flutter - 传递scrollController 时 CustomScrollView 滚动行为会发生变化

Flutter 将函数传递给 TextEditingController(text)

dart - 从 Flutter 中的 List<Widget> 中删除 Index wise CustomWidget

flutter - 屏幕底部的SliverAppBar( flutter )

flutter - 在Flutter中最小化SliverAppBar时,是否有办法查看内容?

swift - flutter/dart 中 swift 的 DispatchGroup 的替代方案是什么?

javascript - 用于推送通知的Firebase云功能不起作用

python - 如何在后台运行时使用flutter应用程序截屏