Flutter使用官方CustomScrollView实现复杂页面下拉刷新和加载更多

Flutter 中官方提供CustomScrollView,让我们能够作何Appbar折叠的效果,并且很容易就能实现下拉刷新和加载更多。

class ScrollableDemoState extends State {
ScrollController _controller;
int _count = 10;
bool _isLoding = false;
bool _isRefreshing = false;
String loadingText = "加载中.....";

@override
void initState() {
super.initState();
_controller = ScrollController();
}

@override
void dispose() {
super.dispose();
_controller.dispose();
}

@override
Widget build(BuildContext context) {
return new MaterialApp(
  home: Scaffold(
    body: new Container(
      child: new NotificationListener(
        onNotification: (notification) {
          if (notification is ScrollUpdateNotification &&
              notification.depth == 0 &&
              !_isLoding &&
              !_isRefreshing) {
            if (notification.metrics.pixels ==
                notification.metrics.maxScrollExtent) {
              setState(() {
                _isLoding = true;
                loadingText = "加载中.....";
                _count += 10;
              });
              _RrefreshPull().then((value) {
                print('加载成功.............');
                setState(() {
                  _isLoding = false;
                });
              }).catchError((error) {
                print('failed');
                setState(() {
                  _isLoding = true;
                  loadingText = "加载失败.....";
                });
              });
            }
          }
        },
        child: RefreshIndicator(
          child: CustomScrollView(
            controller: _controller,
            physics: ScrollPhysics(),
            slivers: [
              const SliverAppBar(
                pinned: true,
                title: const Text('复杂布局'),
//                    expandedHeight: 150.0,
//                    flexibleSpace: FlexibleSpaceBar(
//                      collapseMode: CollapseMode.parallax,
//                      title: Text(
//                        '复杂布局',
//                        style: TextStyle(fontSize: 16),
//                      ),
//                    ),
                elevation: 10,
                leading: Icon(Icons.arrow_back),
              ),
              SliverToBoxAdapter(
                child: Container(
                  height: 200,
                  child: new Swiper(
                    itemBuilder: (BuildContext context, int index) {
                      return new Image.network(
                        "http://pic37.nipic.com/20140113/8800276_184927469000_2.png",
                        fit: BoxFit.fill,
                      );
                    },
                    itemCount: 3,
                    pagination: new SwiperPagination(),
                  ),
                ),
              ),
              new SliverToBoxAdapter(
                child: new Container(
                  padding: EdgeInsets.only(top: 10, bottom: 10),
                  child: new Column(
                    children: [
                      new SizedBox(
                          child: new Text(
                        'SliverGrid',
                        style: new TextStyle(fontSize: 16),
                      )),
                      new Divider(
                        color: Colors.grey,
                        height: 20,
                      )
                    ],
                  ),
                ),
              ),
              SliverGrid(
                gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                  maxCrossAxisExtent: 200.0,
                  mainAxisSpacing: 10.0,
                  crossAxisSpacing: 10.0,
                  childAspectRatio: 4.0,
                ),
                delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    return Container(
                      alignment: Alignment.center,
                      color: Colors.teal[100 * (index % 9)],
                      child: Text('SliverGrid item $index'),
                    );
                  },
                  childCount: _count,
                ),
              ),
              new SliverToBoxAdapter(
                  child: new Container(
                padding: EdgeInsets.only(top: 10, bottom: 10),
                color: Colors.green,
                child: new SizedBox(
                    child: new Text(
                  'SliverFixedExtentList',
                  style: new TextStyle(fontSize: 16),
                )),
              )),
              SliverFixedExtentList(
                itemExtent: 50.0,
                delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    return Container(
                      alignment: Alignment.center,
                      color: Colors.lightBlue[100 * (index % 9)],
                      child: Text('SliverFixedExtentList item $index'),
                    );
                  },
                  childCount: _count + 20,
                ),
              ),
              new SliverToBoxAdapter(
                  child: new Container(
                padding: EdgeInsets.only(top: 10, bottom: 10),
                color: Colors.green,
                child: new SizedBox(
                    child: new Text(
                  'SliverGrid',
                  style: new TextStyle(fontSize: 16),
                )),
              )),
              SliverGrid(
                gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                  maxCrossAxisExtent: 200.0,
                  mainAxisSpacing: 10.0,
                  crossAxisSpacing: 10.0,
                  childAspectRatio: 4.0,
                ),
                delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    return Container(
                      alignment: Alignment.center,
                      color: Colors.teal[100 * (index % 9)],
                      child: Text('SliverGrid item2 $index'),
                    );
                  },
                  childCount: _count + 10,
                ),
              ),
              new SliverToBoxAdapter(
                child: new Visibility(
                  child: new Container(
                    padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
                    child: new Center(
                      child: new Text(loadingText),
                    ),
                  ),
                  visible: _isLoding,
                ),
              ),
            ],
          ),
          onRefresh: () {
            if (_isLoding) return null;
            return _RrefreshPull().then((value) {
              print('success');
              setState(() {
                _count += 10;
              });
            }).catchError((error) {
              print('failed');
            });
          },
        ),
      ),
    ),
  ),
);
}

Future _RrefreshPull() async {
await Future.delayed(new Duration(seconds: 3));
return "_RrefreshPull";
}
}

class ScrollableDemo extends StatefulWidget {
@override
State createState() {
return ScrollableDemoState();
 }
}

实现这些效果在Android中确实要废些时间,但是如果在Flutter中那是分分钟的事,在Flutter中提供了 Sliver族,包含:

  • SliverAppBar:
    实现AppBar的,可以折叠凳=等效果,而且是仅仅配置一个属性就行了。

  • SliverGrid和SliverFixedExtentList:
    见名思议,就是实现网格布局和列表的,没什么好说。

  • SliverToBoxAdapter:
    在CustomScrollView中直接child只能使用Sliver族的widget,如果你要使用其他的就error,所以你需要它SliverToBoxAdapter,注意一定要在外层包裹一层容器组件。

你可能感兴趣的:(Flutter使用官方CustomScrollView实现复杂页面下拉刷新和加载更多)