暗恋的人总是经过一段暗恋后变得坚强,也已成长,成长到接受别人的爱,亦或去追求所爱,而这一切,好像与那个人无关。那个人何其无辜,被爱时他丝毫不知情,被爱后别人的坚强也好似和他无关,但不得不承认,他无意中造就了一个人的蜕变和成长,所以,那个人,又是何其伟大。
今日效果图:
效果图(1.1)
:
分析:
使用NestedScrollView(),SliverAppBar(),TabBar()构建整体框架
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: initNestedScrollView(),
);
NestedScrollView initNestedScrollView() {
return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
///初始化SliverAppBar
initSliverAppBar(),
];
},
//初始化TabBar
body: _initTabBarView(),
);
}
}
初始化SliverAppBar:
///SliverAppBar
Widget initSliverAppBar() {
return SliverAppBar(
expandedHeight: 280,
//当snap = true时 这个参数必须为true!!!
floating: false,
//AppBar固定
pinned: true,
//AppBar跟随手指滑动而滑动 floating必须为true才可以使用
snap: false,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
background: initPageView(),
),
title: InkWell(
onTap: () {
Toast.toast(context, msg: "点击了搜索");
},
child: Container(
height: 38,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.white),
borderRadius: BorderRadius.circular(20)),
alignment: Alignment.center,
child: Text(
"搜索",
style: TextStyle(color: Colors.black, fontSize: 18),
),
),
),
bottom: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 44),
child: TabBar(
controller: _tabController,
//Tab控制条颜色
indicatorColor: Colors.blue,
//字体颜色
labelColor: Colors.black,
//Tab粗细
indicatorWeight: 3,
//设置Tab字体与控制器一样大
indicatorSize: TabBarIndicatorSize.label,
//Tab是否平分
isScrollable: false,
tabs: [
Tab(
child: Text(
"数学",
),
),
Tab(
child: Text(
"英语",
),
),
],
),
),
);
}
SliverAppBar不了解的参考Flutter Slider大家族之SliverAppBar() 组件①
初始化:TabBarView():
class _CustomScrollWidget2State extends State<CustomScrollWidget2>
with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
super.initState();
//Tab控制器
initTabController();
}
void initTabController() {
_tabController = new TabController(
vsync: this,
length: 2,
);
}
///TabBar
Widget _initTabBarView() {
return TabBarView(
controller: _tabController,
children: [
initListView("数学"),
initListView("英语"),
],
);
}
//初始化ListView
initListView(String s) {
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
alignment: Alignment.center,
child: Text("$s$index"),
);
},
itemCount: 30,
);
}
}
这段代码很简单,通过初始化TabBarView在TabBarView’页面’添加ListView
这里需要注意的是:
他们三者参数一定要对应起来!!
比如我现在TabController中length参数为2,那么我的TabBarView参数children[]就必须有2个子条目,Tab()参数也必须有2个
来看看现在的效果:
效果图(1.2)
:
PageView参数 | 类型 | 说明 |
---|---|---|
scrollDirection | Axis | 设置滚动方向Axis.vertical垂直滚动 Axis.horizontal |
controller | PageController | 控制器 |
onPageChanged | ValueChanged |
响应当前页数 |
children | List |
子Page的Widget |
PageController参数 | 类型 | 说明 |
---|---|---|
viewportFraction | double | 设置每一个Page不占满屏幕,漏出上一个和下一个Page! |
initialPage | int | 设置默认显示page |
keepPage | bool | 是否保存当前page状态 |
//初始化PageView
Widget initPageView() {
return Stack(
children: [
//PageView
buildPageView(),
],
);
}
//创建PageView
Widget buildPageView() {
return Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: PageView(
controller: _pageController,
children: [
initPageItem(Colors.deepPurple, "Page1"),
initPageItem(Colors.deepOrange, "Page2"),
initPageItem(Colors.yellow, "Page3"),
initPageItem(Colors.lightGreenAccent, "Page4"),
],
onPageChanged: (index) {
setState(() {
_index = index;
});
},
),
);
}
Widget initPageItem(Color color, String title) {
return Container(
decoration:
BoxDecoration(color: color, borderRadius: BorderRadius.circular(20)),
alignment: Alignment.center,
child: Text(title),
);
}
PageController(PageView控制器):
PageController _pageController;
//默认从0开始
int _index = 0;
@override
void initState() {
// TODO: implement initState
super.initState();
_pageController = PageController(
viewportFraction: 0.9, //设置每一个Page不占满屏幕,漏出上一个和下一个Page!
initialPage: _index, //设置默认Page
keepPage: true //是否保存当前滚动page
);
}
效果图(1.3)
:
使用层叠布局,在PageView下面创建圆点
//初始化PageView
Widget initPageView() {
return Stack(
children: [
//PageView
buildPageView(),
//滑动圆点
buildRound(),
],
);
}
//默认从0的位置开始
int _index = 0;
//滑动圆点
Positioned buildRound() {
return Positioned(
left: 20,
right: 20,
bottom: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
initRound(_index == 0),
initRound(_index == 1),
initRound(_index == 2),
initRound(_index == 3),
],
),
);
}
使用AnimatedContainer()动画初始化圆:
//初始化圆
Widget initRound(bool isselect) {
return AnimatedContainer(
duration: Duration(milliseconds: 800),
width: isselect ? 30 : 10,
height: 10,
margin: EdgeInsets.only(left: 5, right: 5),
curve: Curves.fastOutSlowIn,
decoration: BoxDecoration(
color: isselect ? Colors.black : Colors.white,
borderRadius: BorderRadius.circular(20),
),
);
}
AnimatedContainer不熟悉的请参考Flutter Animated动画(2.7)
来看看现在的效果:
效果图(1.4):
使用Timer使PageView()每过3s自动滑动
Timer _timer;
int _index = 0;
@override
void initState() {
super.initState();
_timer = new Timer.periodic(new Duration(seconds: 3), (timer) {
if (mounted) {
setState(() {
_index++;
if (_index == 4) {
_index = 0;
}
//设置PageView滑动到的页面
_pageController.animateToPage(_index,
duration: Duration(seconds: 2), curve: Curves.ease);
});
}
});
}
效果图(1.5)
:
使用RefreshIndicator完成加载更多
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: RefreshIndicator(
//下拉刷新回调方法
onRefresh: initRefresh;
//可滚动组件在滚动时会发送ScrollNotification类型的通知
notificationPredicate: (ScrollNotification notifation) {
//该属性包含当前ViewPort及滚动位置等信息
ScrollMetrics scrollMetrics = notifation.metrics;
if (scrollMetrics.minScrollExtent == 0) {
return true;
} else {
return false;
}
},
//NestedScrollView(
child: initNestedScrollView(),
),
);
}
initRefresh() async {
//模拟网络刷新 等待2秒
await Future.delayed(Duration(milliseconds: 2000)).then((value) {
Toast.toast(context, msg: "已刷新");
});
//返回值以结束刷新
return Future.value(true);
}
一般会使用 NestScrollView 结合 SliverAppBar, TabBarView 还有下拉刷新组件 RefreshIndicator 来组合实可折叠头部的UI布局文件。 但是在使用官方的下拉刷新 RefreshIndicator发现没法使用,如果使用了折叠效果会消失。
原因是:
默认的RefreshIndicator要求它的子child必须是第一层的滑动组件它才其效果
在来看看最终效果:
效果图(1.6)
:
完整代码
完整项目
猜你喜欢:
Flutter Sliver大家族之CustomScrollView和SliverAppBar 组件①
Flutter Sliver大家族之SliverList(),SliverFixedExtentList(),SliverGrid()组件②
Flutter Sliver大家族之SliverPersistentHeader()和SliverToBoxAdapter()组件③
原创不易,您的点赞就是对我最大的支持,点个赞支持一下吧~