Flutter:如何使用 SliverList 将 CupertinoActivityIndi​​cator 放入 customScrollView

标签 flutter flutter-sliver

这是我想要实现的模型 - 它是 CupertinoSliverNavigationBar 下的 CupertinoActivityIndi​​cator,用于通知用户正在下载数据。 enter image description here

下载完成后,应该是这样的:

enter image description here

现在,我一直在尝试使用以下代码来获得这种效果:

 List<Trade> trades = [];

  showLoadingDialog() {
    return trades.length == 0;
  }

  getBody() {
    if (showLoadingDialog()) {
      return getProgressDialog();
    } else {
      return getTradeItemList();
    }
  }

  getTradeItemList() {
    return new CupertinoPageScaffold(
        child: new CustomScrollView(slivers: <Widget>[
      const CupertinoSliverNavigationBar(
        largeTitle: const Text('Coffee Shop'),
      ),
      getBody(),
    ]));
  }

  getProgressDialog() {
    return new Container(
        decoration: const BoxDecoration(
          color: CupertinoColors.white,
        ),
        child: new Center(child: const CupertinoActivityIndicator()));
  }

但是,我收到此错误是因为我试图将非 RenderSliv​​er 类型放入 Sliver 中。换句话说,我将 CupertinoActivityIndi​​cator 放入 Sliver 中,但代码拒绝了它。

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ The following assertion was thrown building Container(bg: BoxDecoration(color: Color(0xffffffff))): A RenderViewport expected a child of type RenderSliver but received a child of type RenderDecoratedBox. RenderObjects expect specific types of children because they coordinate with their children during layout and paint. For example, a RenderSliver cannot be the child of a RenderBox because a RenderSliver does not understand the RenderBox layout protocol.

最接近我想要的效果显示在下面的 gif 中。但是,您可以清楚地看到,当 CupertinoActivityIndi​​cator 可见时,CupertinoSliverNavigationBar 未显示。只有在下载数据后,才能看到显示“Coffee Shop”的 CupertinoSliverNavigationBar。

enter image description here

我使用以下代码实现了上述目标:

  List<Trade> trades = [];

  showLoadingDialog() {
    return trades.length == 0;
  }

  getBody() {
    if (showLoadingDialog()) {
      return getProgressDialog();
    } else {
      return getTradeItemList();
    }
  }

  getProgressDialog() {
    return new Container(
        decoration: const BoxDecoration(
          color: CupertinoColors.white,
        ),
        child: new Center(child: const CupertinoActivityIndicator()));
  }


  getTradeItemList() {
    return new CupertinoPageScaffold(
      child: new CustomScrollView(
        slivers: <Widget>[
          const CupertinoSliverNavigationBar(
            largeTitle: const Text('Coffee Shop'),
          ),
          new SliverPadding(
            // Top media padding consumed by CupertinoSliverNavigationBar.
            // Left/Right media padding consumed by Tab1RowItem.
            padding: MediaQuery
                .of(context)
                .removePadding(
                  removeTop: true,
                  removeLeft: true,
                  removeRight: true,
                )
                .padding,
            sliver: new SliverList(
              delegate: new SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  return new Tab1RowItem(
                    index: index,
                    lastItem: index == trades.length - 1,
                    color: "Coffee Beans",
                    colorName: "Buy coffee now",
                  );
                },
                childCount: trades.length,
              ),
            ),
          )
        ],
      ),
    );
  }


  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return getBody();
  }

  @override
  void initState() {
    super.initState();
    loadDataTrades();
  }

谁能告诉我怎样才能达到我想要的效果?

最佳答案

 Widget _mainFrame;


@override
  Widget build(BuildContext context) {
    return new CustomScrollView(
      slivers: <Widget>[

        new CupertinoSliverNavigationBar(
          largeTitle: const Text("Coffe Shop"),
        ),

        _mainFrame,

      ],
    );
  }


Widget _beforeDataLoaded() {
    return new SliverFillRemaining(
      child:  new Container(
        child: new Center(
          child: new CupertinoActivityIndicator(),
        ),
      ),
    );
  }



Widget _dataLoadComplete() {
    return new SliverList(
      // Your list items
    );
  }

如果加载完成,您将 _mainFrame 小部件从 CupertionActivityIndi​​cator 更改为您的 ListView 。

关于Flutter:如何使用 SliverList 将 CupertinoActivityIndi​​cator 放入 customScrollView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49840794/

相关文章:

flutter - NestedScrollView with tabbarview scrolling not fired

flutter - 使用 Streambuilder 包装 CustomScrollView 和 Sliverlist 会引发异常

flutter - 加载带有JPG扩展名或PNG的图像

firebase - 不能将 'AuthResult'类型的值分配给 'FirebaseUser'类型的变量

ios - Flutter-Firebase phone Auth 总是在 iOS 上返回 token 不匹配

Flutter Pin/密码/模式集成

带有选项卡覆盖内容的 Flutter SliverAppBar

flutter - Navigator.push可以和Flutter三元一起使用吗

flutter - 如何将 ReorderableListView 放入 Sliver 中?