首页 > 解决方案 > 在 Flutter 中放置一个使用剩余空间但不是 slivers 列表中的最后一个小部件的可滚动列表

问题描述

Flutter 的新手并努力实现一种布局,即动作保留在视图的底部,并且在它们上方有一个可滚动的列表,该列表使用一些同级小部件切割后剩余的空间。如下所示:

我在文档中看到 SliverGrid 比使用许多 SliverToBoxAdapter 小部件更可取,但到目前为止,无论我尝试哪种机智,我都会在列表中出现 RenderBox 错误,除非我用固定高度的容器包装它,这不是我想要的。

如果 SliverFillRemaining 不需要位于其余小部件的底部,那将是完美的。

到目前为止的代码如下,但是我将不胜感激有关实现所需布局的任何方法的任何建议。我希望有一种非常简单的方法可以做到这一点,但我看不到它。

import 'package:flutter/material.dart';

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Slivers Headache',
      home: Scaffold(
        resizeToAvoidBottomInset: true,
        body: CustomScrollView(
          slivers: <Widget>[
            // an app bar
            const SliverAppBar(
              primary: true,
              flexibleSpace: FlexibleSpaceBar(
                  title: Text('Slivers')
              )
            ),
            // a text field
            SliverToBoxAdapter(
              child: TextField(
              controller: TextEditingController(text: 'Text1'),
              onChanged: (value) => {},
              decoration: const InputDecoration(
                border: OutlineInputBorder()),
              )
            ),
            // another text field
            SliverToBoxAdapter(
              child: TextField(
                controller: TextEditingController(text: 'Text1'),
                onChanged: (value) => {},
                decoration: const InputDecoration(border: OutlineInputBorder()),
              )
            ),
            // a checkbox
            SliverToBoxAdapter(
              child: CheckboxListTile(
                tristate: false,
                title: const Text('checkbox'),
                value: false,
                onChanged: (bool? value) => {},
              )
            ),
            // wish I could make a scrollable list view here that takes up remaining vertical space
            SliverList(
              delegate: SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  return ListTile(
                    title: Text('Wish I could fill and scroll $index'),
                  );
                },
                childCount: 3,
              )
            ),
            // some actions
            SliverToBoxAdapter(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  TextButton(
                    child: const Text('Confirm'),
                    onPressed: () {
                      print('Confirmed');
                      Navigator.pop(context);
                    }
                  ),
                  TextButton(
                    child: const Text('Cancel'),
                    onPressed: () {
                      print('Cancelled');
                      Navigator.pop(context);
                    }
                  )
                ]
              )
            )
          ]
        )
      )
    );
  }
}

标签: flutterdartlayout

解决方案


Scaffold 具有bottomSheet 属性,类似于底部导航栏。它将始终位于其下方内容的底部和顶部。(这应该是一个评论,但我没有足够的代表:)


推荐阅读