Flutter:如何将RefreshIndicator与SliverAppBar配合使用

vltsax25  于 2022-12-27  发布在  Flutter
关注(0)|答案(6)|浏览(217)

我正在尝试将RefreshIndicator添加到CustomScrollView中。是否可以这样做?下面是代码示例:

CustomScrollView(
  slivers: <Widget>[
    SliverAppBar(
      title: Text('POSTAPP'),
      centerTitle: true,
      floating: true,
      pinned: false,
    ),
    SliverList(
        delegate: SliverChildBuilderDelegate(
          _createPostItem,
          childCount: postRepo.posts.length,
      ),
    ),
  ],
);
xtupzzrd

xtupzzrd1#

如果不一定限制使用CustomScrollView,那么使用NestedScrollView可以实现您的要求:

@override
Widget build(BuildContext context) {
  return NestedScrollView(
    headerSliverBuilder: (context, innerBoxScrolled) => [
          SliverAppBar(
            title: Text('POSTAPP'),
            centerTitle: true,
            floating: true,
            pinned: false,
          ),
        ],
    body: RefreshIndicator(
      onRefresh: _loadMorePosts,
      child: ListView.builder(
        itemBuilder: _createPostItem,
        itemCount: _postsCount,
      ),
    ),
  );
}
gywdnpxw

gywdnpxw2#

只有这样:

RefreshIndicator(child: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            title: Text('POSTAPP'),
            centerTitle: true,
            floating: true,
            pinned: false,
          ),
          SliverList(
              delegate: SliverChildBuilderDelegate(_createPostItem,
                  childCount: postRepo.posts.length))
        ],
      ), onRefresh: () => Future.value(true));

SliverList是不可滚动的,所以不能用RefreshIndicator Package 它

4nkexdtk

4nkexdtk3#

对于任何想回到这个问题的人,我已经找到了一个使用pull_to_refresh包的解决方案。

final RefreshController _refreshController = RefreshController();

Future<void> _onRefresh() async {
  await Future<void>.delayed(const Duration(milliseconds: 1000));
  _refreshController.refreshCompleted();
}

@override
Widget build(BuildContext context) {
  return CustomScrollView(
    slivers: [
      SliverAppBar(
        title: Text('Title'),
        centerTitle: true,
        floating: true,
        pinned: false,
      ),
      SliverFillRemaining(
        child: SmartRefresher(
          controller: _refreshController,
          onRefresh: _onRefresh,
          // ListView, CustomScrollView, etc. here
          child: SingleChildScrollView(
            child: Column(
              children: [
                Container(
                  height: 200,
                  color: Colors.red,
                ),
                Container(
                  height: 200,
                  color: Colors.blue,
                ),
                Container(
                  height: 200,
                  color: Colors.yellow,
                ),
              ],
            ),
          ),
        ),
      ),
    ],
  );
}
k97glaaz

k97glaaz4#

This is the answer

    RefreshIndicator(
    onRefresh: () async {
      return await Future.delayed(const Duration(seconds: 2));
    },
    edgeOffset: 100,   // ANY NUMBER SO THE REFRESH APPEARS ANYWHERE YOU WANT.
    child: CustomScrollView(
        slivers: <Widget>[
            SliverAppBar(
                title: Text('POSTAPP'),
                centerTitle: true,
                floating: true,
                pinned: false,
            ),
            SliverList(
                delegate: SliverChildBuilderDelegate(
                    _createPostItem,
                    childCount: postRepo.posts.length,
                ),
            ),
        ],
     ),
);
u5rb5r59

u5rb5r595#

我设法通过创建一个自定义的小部件,从flutter/lib/src/material/refresh_indicator. dart.和修改以下代码(p.s i只添加了变量initialDisplacement

double initialDisplacement = 100.0;
return Stack(
  children: <Widget>[
    child,
    if (_mode != null) Positioned(
      top: _isIndicatorAtTop ? initialDisplacement : null,
      bottom: !_isIndicatorAtTop ? 0.0 : null,
      left: 0.0,
      right: 0.0,
      child: SizeTransition(
        axisAlignment: _isIndicatorAtTop ? 1.0 : -1.0,
        sizeFactor: _positionFactor, // this is what brings it down
        child: Container(
          padding: _isIndicatorAtTop
            ? EdgeInsets.only(top: widget.displacement)
            : EdgeInsets.only(bottom: widget.displacement),
          alignment: _isIndicatorAtTop
            ? Alignment.topCenter
            : Alignment.bottomCenter,
          child: ScaleTransition(
            scale: _scaleFactor,
            child: AnimatedBuilder(
              animation: _positionController,
              builder: (BuildContext context, Widget child) {
                return RefreshProgressIndicator(
                  semanticsLabel: widget.semanticsLabel ?? MaterialLocalizations.of(context).refreshIndicatorSemanticLabel,
                  semanticsValue: widget.semanticsValue,
                  value: showIndeterminateIndicator ? null : _value.value,
                  valueColor: _valueColor,
                  backgroundColor: widget.backgroundColor,
                  strokeWidth: widget.strokeWidth,
                );
              },
            ),
          ),
        ),
      ),
    ),
  ],
);
cnjp1d6j

cnjp1d6j6#

你可以在slivers列表中使用CupertinoSliverRefreshControl,你需要将physics: BouncingScrollPhysics()应用到你的CustomScrollView
示例:

return Scaffold(
      body: CustomScrollView(
        physics: BouncingScrollPhysics(),
        slivers: [
          SliverAppBar(),
          CupertinoSliverRefreshControl(
            onRefresh: () => refreshList(),
          ),
          SliverList(delegate: delegate),
        ],
      ),
    );

在上面的示例中,RefreshIndicator显示在AppBarListView之间。

相关问题