【问题标题】:SliverAppBar() not collapsing with ListView in FlutterSliverAppBar() 不与 Flutter 中的 ListView 折叠
【发布时间】:2020-01-16 21:55:05
【问题描述】:

我正在尝试在SliverAppBar() 中显示每个主选项卡(嵌套选项卡栏)的选项卡。它看起来像这样:

See the image

See the GIF

Container() 小部件中的考试选项卡的内容(图像中的错误来自)。 现在,使用 Container() 小部件时,SliverAppBar() 将在用户滚动考试选项卡内容(图像中的白屏)时折叠,现在一切都很好。

所以,在我用ListView.builder() 替换Container() 以使标签内容可滚动后,现在我无法从标签内容中折叠SliverAppBar()(图像中的白屏)。但我可以从SliverAppBar()

See this GIF after I added ListView.builder()

那么,如何使用 Listview 使 SliverAppBar 可滚动(折叠)? 可以有人帮助我吗?请:(

这个例子(演示):

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(title: 'SliverAppBar App Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: DefaultTabController(
          length: 2,
          child: NestedScrollView(
            headerSliverBuilder:
                (BuildContext context, bool innerBoxIsScrolled) {
              return [
                SliverOverlapAbsorber(
                  handle:
                      NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                  child: SliverSafeArea(
                    top: false,
                    sliver: SliverAppBar(
                      pinned: true,
                      title: Text(widget.title),
                      expandedHeight: 500,
                    ),
                  ),
                ),
                SliverPersistentHeader(
                  delegate: _SliverAppBarDelegate(
                    TabBar(tabs: [Tab(text: 'Tab A'), Tab(text: 'Tab B')]),
                    Colors.blue,
                  ),
                  pinned: false,
                ),
              ];
            },
            body: TabBarView(
              children: <Widget>[
                NestedTabs('A'),
                NestedTabs('B'),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// This class is to handle the main tabs (Tab A & Tab B)
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverAppBarDelegate(this._tabBar, this._color);

  TabBar _tabBar;
  final Color _color;

  @override
  double get minExtent => _tabBar.preferredSize.height;
  @override
  double get maxExtent => _tabBar.preferredSize.height;

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return new Container(
      color: _color,
      alignment: Alignment.center,
      child: _tabBar,
    );
  }

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
    return false;
  }
}

class NestedTabs extends StatelessWidget {
  final String mainTabName;
  NestedTabs(this.mainTabName);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        preferredSize: Size.fromHeight(20),
        child: Container(
          color: Colors.blue,
          alignment: Alignment.bottomCenter,
          child: TabBar(
            tabs: [
              Tab(text: 'Tab $mainTabName-1'),
              Tab(text: 'Tab $mainTabName-2')
            ],
          ),
        ),
      ),
      body: TabBarView(
        children: [
          ListView.builder(
            padding: const EdgeInsets.all(8),
            itemCount: 500,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                  height: 50,
                  width: 200,
                  color: Colors.black45,
                  child: Center(child: Text('Index ${index}')));
            },
          ),
          ListView.builder(
            padding: const EdgeInsets.all(8),
            itemCount: 500,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                  height: 50,
                  width: 200,
                  color: Colors.black45,
                  child: Center(child: Text('Index ${index}')));
            },
          )
        ],
      ),
    );
  }
}


谢谢你:)

【问题讨论】:

  • 你有大量的信息,没有具体的问题。请查看问题指南:stackoverflow.com/help/how-to-ask
  • 对不起,但我认为这很清楚 :(。我的问题是如何使用 Listview 使 SliverAppBar 可滚动(折叠)
  • 我建议您删除所有与您的问题无关的代码和描述,只留下必要的部分。
  • 谢谢,我更新了代码并写了完整的例子
  • 我也遇到过同样的问题,@JoãoSoares 很清楚这个问题,你为什么说不清楚。 GIF 说明了一切。

标签: flutter dart flutter-sliver


【解决方案1】:

使用 SliverList() 代替 ListView 的 SliverFillRemaining

【讨论】:

    猜你喜欢
    • 2019-10-31
    • 1970-01-01
    • 2020-07-03
    • 2021-01-22
    • 1970-01-01
    • 2018-03-30
    • 2019-05-11
    • 2020-11-29
    • 2023-01-13
    相关资源
    最近更新 更多