flutter:使用 RefreshIndicator 时没有刷新指示器

问题描述 投票:0回答:14

我在页面中添加了 RefreshIndicator,但是拉动刷新时没有可见的指示器。代码如下:

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

  final String title;

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

class _MyHomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: LocalGalleryTab(),
    );
  }
}

class LocalGalleryTab extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _LocalGalleryState();
  }
}

class _LocalGalleryState extends State<LocalGalleryTab> {
  @override
  Widget build(BuildContext context) {
    return new Container(child: new Center(
      child: new RefreshIndicator(
        child: Text("Local Gallery"),
        onRefresh: _refreshLocalGallery,
      ),
    ));
  }

  Future<Null> _refreshLocalGallery() async{
    print('refreshing stocks...');

  }
}

如何使用刷新指示器? flutter doc 没有提供太多信息。

flutter dart refresh pull-to-refresh indicator
14个回答
73
投票

刷新指示器默认不适用于短列表,因此将以下内容添加到 ListView.builder

physics: const AlwaysScrollableScrollPhysics(),

63
投票

按照设计,

RefreshIndicator
ListView
配合使用。

但是如果您想将

RefreshIndicator
与不可滚动小部件一起使用,您可以使用
Stack
将您的小部件包装到
ListView
中:

RefreshIndicator(
  onRefresh: () {},
  child: Stack(
    children: <Widget>[ListView(), YOUR_CHILD_WIDGET],
  ),
),

36
投票

您需要在里面添加滚动子项

RefreshIndicator
请参阅下面的示例

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

  final String title;

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

class _MyHomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: LocalGalleryTab(),
    );
  }
}

class LocalGalleryTab extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _LocalGalleryState();
  }
}

class _LocalGalleryState extends State<LocalGalleryTab> {
  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
        child: ListView(
          children: List.generate(50,  (f) => Text("Item $f")),
        ),
        onRefresh: _refreshLocalGallery,
      );
  }

  Future<Null> _refreshLocalGallery() async{
    print('refreshing stocks...');

  }
}

17
投票
RefreshIndicator(
   onRefresh: _onRefresh,
   child:SingleChildScrollView(
   physics: AlwaysScrollableScrollPhysics(),
   child: ListView(
   padding: EdgeInsets.all(8.0),

   children: _listData.map((i) {
    return ListTile(
      title: Text("Item $i"),
    );
  }).toList(),
 )
)
);

在 SingleChildScrollView 中添加物理


2
投票

您也可以将 ListView 与 SinglchildScrollView 小部件一起使用。

    RefreshIndicator(
      onRefresh: () {
         //HERE YOUR FUNCTION TO CALL
      },
      child: Stack(
        children: <Widget>[
              ListView(
                physics: const AlwaysScrollableScrollPhysics(),
                 children: []
                )
              ],
            ),
        ),

2
投票

在对当前页面中已经存在的一个答案进行少量更改后,我得到了这个问题的解决方案! 只需更改堆栈子级的位置(首先是主窗口小部件,然后是列表视图)。

更新后的答案将100%有效:

RefreshIndicator(
      onRefresh: () {},
      child: Stack(
        children: <Widget>[YOUR_CHILD_WIDGET, ListView()],
      ),
    ),

以上答案的过去答案:

RefreshIndicator(
  onRefresh: () {},
  child: Stack(
    children: <Widget>[ListView(), YOUR_CHILD_WIDGET],
  ),
),

1
投票

我认为迄今为止最好的方法是将 CustomScrollView 与 RefreshIndicator 结合使用。请参阅下面的示例。

class RefreshDemo extends StatelessWidget {
  const RefreshDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      onRefresh: () async {
        // Your refresh logic goes here
        await Future.delayed(Duration(seconds: 2));
        return true;
      },
      child: CustomScrollView(
        slivers: [
          // Wrap your widgets with the SliverToBoxAdapter
          SliverToBoxAdapter(
            child: Container(
              child: Column(
                children: [
                  Text('Hello'),
                  Text('World'),
                
                ]
              )
            ),
          ),
        ],
      ),
    );
  }
}

1
投票

在不可滚动的列表视图中,RefreshIndicator不起作用,所以你必须用Stack包裹你的widget来实现下拉刷新。

RefreshIndicator(
  onRefresh: () {
  // Refresh Functionality 
  },
  child: Stack(
            children: [
              ListView(
                padding: EdgeInsets.zero,
                shrinkWrap: true,
                children: [
                  SizedBox(
                    height: MediaQuery.of(context).size.height,
                  )
                ],
              ),
              // Your Widget 
            ],
          );
        ),

1
投票

最重要的是在ListView中实现:

物理:const AlwaysScrollableScrollPhysics(),

因为否则未覆盖整个屏幕的项目会被卡住,您无法移动/刷新它们。


1
投票

始终确保您没有在 Listview 中使用 BouncingScrollPhysics(),因为它不允许刷新。


0
投票

RefreshIndicator 与 ListView 配合使用..

RefreshIndicator(
    onRefresh: () {},
    child: ListView.builder(
        itemCount: 1, //just to build the Widget once..
        itemBuilder:(context, index) => //your Widget..
    )
)

0
投票

就我而言,它不起作用 -

 RefreshIndicator(
 onRefresh: () {return fetchData(); },
 color: colorPrimary,
 child:  Column( children: [...],)]

最后,我用列表视图包装我的专栏,然后它就可以工作了 -

 RefreshIndicator(
 onRefresh: () {return fetchData(); },
 color: colorPrimary,
 child:  ListView(
         children:[Column( children: [...],)])

0
投票

通过使用 AlwaysScrollableScrollPhysics() 现在列表不会滚动。

 SizedBox(
                          
                          child: RefreshIndicator(
                            onRefresh: searchController.getAllArtist,
                            child: Padding(
                              padding: EdgeInsets.symmetric(horizontal: size.width * 0.02),
                              child: ListView.separated(
                                  physics: const AlwaysScrollableScrollPhysics(),
                                  controller: _scrollController,
                                  shrinkWrap: true,
                                  itemBuilder: (context, index) {
                                   if(index<searchController.searchedArtist.length){
                                     return InkWell(
                                       onTap: (){
                                         PersistentNavBarNavigator.pushNewScreen(context,
                                             screen: UserPublicProfile(artistID: searchController.searchedArtist[index]['id'].toString()));
                                       },
                                       child: artistCard(index: index,),
                                     );
                                   }
                                   else{
                                     return Center(child: CircularProgressIndicator(color: primaryAlizarinColor,));
                                   }
                                  },
                                  separatorBuilder: (context, index) {
                                    return const SizedBox(
                                      height: 20,
                                    );
                                  },
                                  itemCount: searchController.searchedArtist.length+(isLastitem.isTrue?0:1)),
                            ),
                          ),
                        )

-1
投票

如上所述,刷新指示器仅适用于 Listview,因此请使用它,否则将 Listview 与 Stack 一起使用

© www.soinside.com 2019 - 2024. All rights reserved.