【问题标题】:Flutter: How to put a CupertinoActivityIndicator into a customScrollView with SliverListFlutter:如何使用 SliverList 将 CupertinoActivityIndi​​cator 放入 customScrollView
【发布时间】:2018-09-25 05:14:17
【问题描述】:

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

下载后应该是这样的:

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

 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 并且代码拒绝它。

══╡ 小部件库发现异常 ╞═════════════════════════════════════════════════ ══════════ 以下断言被抛出构建 Container(bg: BoxDecoration(color: Color(0xffffffff))): A RenderViewport 预期 RenderSliv​​er 类型的子级,但收到了一个子级 渲染装饰框。 RenderObjects 期望特定类型的孩子 因为他们在布局和绘画过程中与孩子协调。 例如,RenderSliv​​er 不能是 RenderBox 的子级,因为 一个 RenderSliv​​er 不理解 RenderBox 布局协议。

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

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

  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();
  }

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

【问题讨论】:

  • 这很混乱,你不应该做这样的事情吗@override Widget build(BuildContext context) { // TODO: implement build return CupertinoPageScaffold( child: _loaded?_buildBody():new Center( child: new CupertinoActivityIndicator(), ), ); }
  • 那并不能解决问题 - 如果没有数据,您的建议只会生成 cupertinoactivityindicator,并且我想要实现的 CupertinoSliverNavigationBar 上不会出现“咖啡店”标题。
  • return _loaded? new Tab1RowItem(...) : new Center( child: new CupertinoActivityIndicator(), ), ??

标签: flutter flutter-sliver


【解决方案1】:
 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 更改为您的列表视图。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2021-02-14
    • 1970-01-01
    • 2020-04-29
    • 2021-08-01
    • 1970-01-01
    相关资源
    最近更新 更多