当前位置:   article > 正文

使用container的嵌套实现下面布局_# flutter使用Sliver实现折叠布局

headersliverbuilder

aa52bd6fa60c08bdcad5392ab4645a40.png

flutter使用Sliver实现折叠布局

[toc]

效果预览

实操

页面分析

我们具体看下页面,上面是一个banner,banner下面是一个商品分类,然后一个可以切换滚动的menuBar. 相信看到这里,android的朋友已经有了思路了:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.design.widget.CoordinatorLayout>
  3. <android.support.design.widget.AppBarLayout> <android.support.design.widget.CollapsingToolbarLayout>
  4. <android.support.v7.widget.Toolbar/> </android.support.design.widget.CollapsingToolbarLayout>
  5. </android.support.design.widget.AppBarLayout>
  6. <android.support.v4.widget.NestedScrollView>
  7. <TextView/>
  8. </android.support.v4.widget.NestedScrollView>
  9. <android.support.design.widget.FloatingActionButton/>
  10. </android.support.design.widget.CoordinatorLayout>

而在flutter中,其实也是有对应的Widget的。 也就是Sliver家族了。

代码实操

我们首先看下代码:

  1. body: NestedScrollView(
  2. headerSliverBuilder: (context, innerBoxIsScrolled) {
  3. return <Widget>[
  4. SliverOverlapAbsorber(
  5. handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
  6. child: SliverAppBar(
  7. automaticallyImplyLeading: false,
  8. forceElevated: innerBoxIsScrolled,
  9. bottom: PreferredSize(
  10. child: Container(),
  11. preferredSize: Size.fromHeight(_allHeight)),
  12. flexibleSpace: Column(
  13. children: <Widget>[
  14. _initPersonInfo(),
  15. _initDetailInfo(),
  16. ],
  17. ),
  18. ),
  19. ),
  20. SliverPersistentHeader(
  21. delegate: SliverAppBarDelegate(_initTabBar()),
  22. pinned: true,
  23. ),
  24. ];
  25. },
  26. body: TabBarView(
  27. controller: _tabController,
  28. children: <Widget>[
  29. IncomeChildPage(),
  30. IncomeChildPage(),
  31. ],
  32. ),
  33. ),

代码分析

懒得写了 就这样吧...干活去了

对比拓展

代码

  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_module_for_balance/delegate/SliverAppBarDelegate.dart';
  3. import 'package:flutter_module_for_balance/page/dialog/ExplainDialog.dart';
  4. import 'package:flutter_module_for_balance/utils/ColorConf.dart';
  5. import 'package:flutter_module_for_balance/utils/PlatformUtils.dart';
  6. import 'package:flutter_module_for_balance/utils/StyleConf.dart';
  7. import 'package:flutter_module_for_balance/utils/ToastUtils.dart';
  8. import 'incomeChild/IncomeChildPage.dart';
  9. /// 现金收益页面
  10. /// 下属 [IncomeChildPage]
  11. ///
  12. ///
  13. /// 页面代理[SliverAppBarDelegate]
  14. class IncomePage extends StatefulWidget {
  15. @override
  16. _IncomePageState createState() => _IncomePageState();
  17. }
  18. class _IncomePageState extends State<IncomePage>
  19. with SingleTickerProviderStateMixin {
  20. // 滑动控制器
  21. TabController _tabController;
  22. // tabMenu分类数据
  23. List<String> _classType;
  24. // 账户信息 也就是cardView高度
  25. double _cardHeight;
  26. // 个人信息 也就是顶部头像高度
  27. double _infoHeight;
  28. // 整个appbar 展开高度
  29. double _allHeight;
  30. @override
  31. void initState() {
  32. _classType = ['总收益明细', '提现记录'];
  33. _tabController = new TabController(length: _classType.length, vsync: this);
  34. super.initState();
  35. }
  36. /// 显示dialog
  37. void _showDialog(BuildContext context) {
  38. showDialog(context: context, builder: (context) => ExplainDialog());
  39. }
  40. @override
  41. Widget build(BuildContext context) {
  42. _cardHeight = PlatformUtils.getWindowHeight(context) * 0.24;
  43. _infoHeight = PlatformUtils.getWindowHeight(context) * 0.10;
  44. _allHeight = _cardHeight + _infoHeight - kToolbarHeight;
  45. return Scaffold(
  46. appBar: AppBar(
  47. elevation: 0,
  48. centerTitle: true,
  49. title: Text(
  50. '现金收益',
  51. style: StyleConf.style1748586DBold,
  52. ),
  53. // leading: GestureDetector(
  54. // child: Icon(
  55. // Icons.arrow_back_ios,
  56. // color: ColorConf.color48586D,
  57. // ),
  58. // onTap: () {
  59. // Navigator.pop(context);
  60. // },
  61. // ),
  62. ),
  63. body: NestedScrollView(
  64. headerSliverBuilder: (context, innerBoxIsScrolled) {
  65. return <Widget>[
  66. SliverOverlapAbsorber(
  67. handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
  68. child: SliverAppBar(
  69. automaticallyImplyLeading: false,
  70. forceElevated: innerBoxIsScrolled,
  71. bottom: PreferredSize(
  72. child: Container(),
  73. preferredSize: Size.fromHeight(_allHeight)),
  74. flexibleSpace: Column(
  75. children: <Widget>[
  76. _initPersonInfo(),
  77. _initDetailInfo(),
  78. ],
  79. ),
  80. ),
  81. ),
  82. SliverPersistentHeader(
  83. delegate: SliverAppBarDelegate(_initTabBar()),
  84. pinned: true,
  85. ),
  86. ];
  87. },
  88. body: TabBarView(
  89. controller: _tabController,
  90. children: <Widget>[
  91. IncomeChildPage(),
  92. IncomeChildPage(),
  93. ],
  94. ),
  95. ),
  96. );
  97. }
  98. /// 初始化tab Menu
  99. /// 这个Widget 可用于bottom以及center中部菜单
  100. /// 可用于 [appBar]的[bottom]
  101. /// 可用于[body]的item
  102. Widget _initTabBar() {
  103. TabBar tabBar = _initTabItem();
  104. return Stack(
  105. alignment: Alignment.center,
  106. children: <Widget>[
  107. Container(
  108. color: ColorConf.colorFFFFFF,
  109. ),
  110. tabBar,
  111. ],
  112. );
  113. }
  114. /// 初始化每一个tabBar的每一个item ,主要用于[_initTabBar]
  115. Widget _initTabItem() {
  116. return TabBar(
  117. onTap: ((index) {
  118. debugPrint('click item is $index');
  119. }),
  120. labelStyle: StyleConf.style1448586D,
  121. unselectedLabelStyle: StyleConf.style14A1A9B4,
  122. indicatorSize: TabBarIndicatorSize.tab,
  123. indicatorColor: ColorConf.color18C8A1,
  124. labelColor: ColorConf.color48586D,
  125. unselectedLabelColor: ColorConf.color929292,
  126. tabs: _classType
  127. .map((e) => Tab(
  128. child: Container(
  129. child: Text(e),
  130. padding: const EdgeInsets.only(
  131. bottom: 0,
  132. ),
  133. ),
  134. ))
  135. .toList(),
  136. controller: _tabController,
  137. );
  138. }
  139. /// 初始化个人信息
  140. Widget _initPersonInfo() {
  141. return GestureDetector(
  142. child: Container(
  143. height: _infoHeight,
  144. child: Row(
  145. children: <Widget>[
  146. Container(
  147. margin: const EdgeInsets.only(left: 22, right: 15),
  148. decoration:
  149. BoxDecoration(borderRadius: BorderRadius.circular(50)),
  150. child: Image.asset(
  151. 'images/tempCirclePic.png',
  152. height: 40,
  153. width: 40,
  154. ),
  155. ),
  156. Text(
  157. 'Colour.Lun',
  158. style: StyleConf.style1448586DBold,
  159. ),
  160. Expanded(
  161. child: Container(
  162. margin: const EdgeInsets.only(right: 22),
  163. alignment: Alignment.centerRight,
  164. child: Text(
  165. '伦彩仪',
  166. style: StyleConf.style1248586D,
  167. ),
  168. ))
  169. ],
  170. ),
  171. ),
  172. onTap: () {
  173. ToastUtils.showTs('个人信息');
  174. },
  175. );
  176. }
  177. /// 详细信息
  178. Widget _initDetailInfo() {
  179. return Container(
  180. height: _cardHeight - 5,
  181. margin: const EdgeInsets.only(left: 22, right: 22, bottom: 5),
  182. child: Container(
  183. padding: const EdgeInsets.only(
  184. left: 28,
  185. right: 28,
  186. ),
  187. child: Column(
  188. crossAxisAlignment: CrossAxisAlignment.start,
  189. children: <Widget>[
  190. Row(
  191. children: <Widget>[
  192. Container(
  193. child: Text(
  194. '可提现现金/元',
  195. style: StyleConf.style13FCFCFC,
  196. ),
  197. margin: const EdgeInsets.only(top: 16),
  198. ),
  199. Expanded(
  200. child: Container(
  201. alignment: Alignment.centerRight,
  202. child: GestureDetector(
  203. child: Container(
  204. padding: const EdgeInsets.only(left: 10, top: 16),
  205. child: Image.asset(
  206. 'images/icon_question.png',
  207. width: 14,
  208. height: 14,
  209. color: ColorConf.colorFFFFFF,
  210. ),
  211. ),
  212. onTap: () {
  213. _showDialog(context);
  214. },
  215. ),
  216. ))
  217. ],
  218. ),
  219. Container(
  220. margin: const EdgeInsets.only(top: 14, bottom: 20),
  221. child: Row(
  222. children: <Widget>[
  223. Text(
  224. '25,992',
  225. style: StyleConf.style30FFFFFF,
  226. ),
  227. Expanded(
  228. child: Container(
  229. alignment: Alignment.centerRight,
  230. child: GestureDetector(
  231. child: Container(
  232. padding: const EdgeInsets.only(
  233. left: 22, right: 22, top: 6, bottom: 6),
  234. decoration: BoxDecoration(
  235. color: ColorConf.colorFFFFFF,
  236. borderRadius: BorderRadius.circular(20)),
  237. child: Text('提现', style: StyleConf.style1418C8A1Bold),
  238. ),
  239. onTap: () {
  240. ToastUtils.showTs('提现按钮');
  241. },
  242. ),
  243. ),
  244. )
  245. ],
  246. ),
  247. ),
  248. Expanded(
  249. child: Container(
  250. child: Row(
  251. children: <Widget>[
  252. Expanded(
  253. child: _itemInfo(alignment: Alignment.centerLeft),
  254. ),
  255. Container(
  256. width: 1,
  257. height: 30,
  258. color: ColorConf.colorFFFFFF,
  259. ),
  260. Expanded(
  261. child: _itemInfo(),
  262. ),
  263. Container(
  264. width: 1,
  265. height: 30,
  266. color: ColorConf.colorFFFFFF,
  267. ),
  268. Expanded(
  269. child: _itemInfo(alignment: Alignment.centerRight),
  270. ),
  271. ],
  272. ),
  273. ),
  274. )
  275. ],
  276. ),
  277. ),
  278. decoration: BoxDecoration(
  279. boxShadow: [
  280. BoxShadow(
  281. color: Color(0x333ADDC5), offset: Offset(0, 10), blurRadius: 20)
  282. ],
  283. borderRadius: BorderRadius.circular(8),
  284. image: DecorationImage(
  285. fit: BoxFit.cover,
  286. image: AssetImage('images/bg_cash.png'),
  287. )),
  288. );
  289. }
  290. /// 分类item信息
  291. Widget _itemInfo({alignment}) {
  292. return Container(
  293. alignment: alignment ?? Alignment.center,
  294. child: Column(
  295. mainAxisAlignment: MainAxisAlignment.center,
  296. children: <Widget>[
  297. Container(
  298. child: Text('总收益/元', style: StyleConf.style12FFFFFF),
  299. margin: const EdgeInsets.only(bottom: 2),
  300. ),
  301. Text('3,176.00', style: StyleConf.style12FFFFFF),
  302. ],
  303. ),
  304. );
  305. }
  306. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/463060
推荐阅读
相关标签