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,注意一定要在外层包裹一层容器组件。