美文网首页Flutter
Flutter上拉加载下拉刷新

Flutter上拉加载下拉刷新

作者: 音符上的码字员 | 来源:发表于2019-03-22 17:13 被阅读17次

    简单学习记录下,flutter的简单的上拉加载下拉刷新

    效果图


    refresh.gif

    上代码

    class RefreshWidget extends StatefulWidget {
    
      @override
      _RefreshState createState() {
        return _RefreshState();
      }
    
    }
    
    class _RefreshState extends State<RefreshWidget> {
      // 用一个key来保存下拉刷新控件RefreshIndicator
      GlobalKey<RefreshIndicatorState> _refreshKey = GlobalKey<RefreshIndicatorState>();
      // 承载listView的滚动视图
      ScrollController _scrollController = ScrollController();
      // 数据源
      List<String> _dataSource = List<String>();
      // 当前加载的页数
      int _pageSize = 0;
    
      // 加载数据
      void _loadData(int index) {
        for (int i=0; i<15; i++) {
          _dataSource.add((i+15*index).toString());
    
        }
      }
    
      // 下拉刷新
      Future<Null> _onRefresh() {
        return Future.delayed(Duration(seconds: 2), () {
          print("正在刷新...");
          _pageSize = 0;
          _dataSource.clear();
          setState(() {
            _loadData(_pageSize);
          });
        });
      }
    
      // 加载更多
      Future<Null> _loadMoreData() {
        return Future.delayed(Duration(seconds: 1), () {
          print("正在加载更多...");
    
          setState(() {
            _pageSize++;
            _loadData(_pageSize);
          });
        });
      }
    
      // 刷新
      showRefreshLoading() {
        new Future.delayed(const Duration(seconds: 0), () {
          _refreshKey.currentState.show().then((e) {});
          return true;
        });
      }
    
      @override
      void initState() {
        showRefreshLoading();
        _scrollController.addListener(() {
          if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
            _loadMoreData();
          }
        });
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return RefreshIndicator(
          key: _refreshKey,
          onRefresh: _onRefresh,
          child: ListView.separated(
            controller: _scrollController,
            padding: EdgeInsets.all(8.0),
            physics: const AlwaysScrollableScrollPhysics(),
            itemBuilder: (buildContext, index) {
              return items(context, index);
            },
            itemCount: _dataSource.isEmpty ? 0 : _dataSource.length+1,
            separatorBuilder: (buildContext, index) {
              return Divider(
                height: 1,
                color: Colors.lightGreen,
              );
            },
          ),
        );
      }
    
      // item控件
      Widget items(context, index) {
        if (index == _dataSource.length) {
          return Container(
            child: Padding(
                padding: const EdgeInsets.all(15.0),
                child: Center(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      CircularProgressIndicator(
                        backgroundColor: Theme.of(context).primaryColor,
                      ),
                      SizedBox(
                        width: 10.0,
                      ),
                      Text(
                        "正在加载",
                        style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 14.0,
                            color: Colors.deepPurple
                        ),
                      )
                    ],
                  ),
                )
            ),
          );
        }
        return Center(
            child: Padding(
              padding: const EdgeInsets.all(20.0),
              child: Text.rich(TextSpan(
                  children: [
                    TextSpan(text: "我是第"),
                    TextSpan(
                        text: "${_dataSource[index]}",
                        style: TextStyle(
                            color: Colors.red,
                            fontSize: 18.0,
                            fontWeight: FontWeight.bold
                        )
                    ),
                    TextSpan(text: "个")
                  ]
              )),
            )
        );
      }
    }
    

    这里有段代码

    // 刷新
      showRefreshLoading() {
        new Future.delayed(const Duration(seconds: 0), () {
          _refreshKey.currentState.show().then((e) {});
          return true;
        });
      }
    

    _refreshKey.currentState.show()表示刷新时的头部,他放在一个延时的异步操作中,当时还在考虑为什么放在异步里,直接在initState里调用不行么,试了一下,报错,错误日志是因为RefreshIndicator为空,也就是图层还没渲染完成,build方法还没执行完,这里加异步是为了等渲染完成后再进行操作,即使延迟时间为0秒。

    另外注意RefreshIndicator这个Widget,里面有一个onRefresh属性,他只接收一个Future对象,所以为什么这里下拉刷新,加载更多方法要设置返回值为Future。

    还有这里的itemCount属性为

     _dataSource.isEmpty ? 0 : _dataSource.length+1
    

    是当没有数据时只有顶部圆圈存在,当有数据时,除了每条数据占据一行以外,当滑到最下面时,有一个加载widget占据一行。

    另外还有flutter_easyrefresh刷新加载这个第三方,改天试试。

    相关文章

      网友评论

        本文标题:Flutter上拉加载下拉刷新

        本文链接:https://www.haomeiwen.com/subject/yxprvqtx.html