CupertinoPageScaffold、CustomScrollView

人间烟火/张佳伟版 Lv2

CupertinoPageScaffold 属性介绍,这是苹果风格的MT

Flutter 组件 CupertinoNavigationBar

| backgroundColor | 背景色
| resizeToAvoidBottomInset | 是否调整自身大小来避免底部嵌入,默认为 true。例如键盘弹起输入时防止输入框和键盘重叠遮挡。
| child @required | 子控件

CupertinoNavigationBar 属性 介绍
属性 解释
leading 左侧组件
automaticallyImplyLeading 是否添加默认 leading,默认为 true。当 leading 为空会默认添加一个返回按钮
automaticallyImplyMiddle 是否添加默认 middle,默认为 true,如果 middle 为空,且当前 route 为 CupertinoPageRoute,会默认填充 route.title
previousPageTitle 当 leading 为空,且 automaticallyImplyLeading == true,会出现在默认返回箭头右边的文字
middle 中间标题组件
trailing 右侧组件
border 边框,默认为 _kDefaultNavBarBorder
backgroundColor 背景色
brightness 上方电量,事件,Wifi 等状态栏颜色
padding 内边距,用来调节所有子组件上下左右偏移
actionsForegroundColor leading 和 trailing 的默认颜色
transitionBetweenRoutes 默认为 true,和滑动动画有关
heroTag 默认为 _defaultHeroTag,和滑动动画有关,需要transitionBetweenRoutes未false

CustomScrollView

注意:此组件可包含很多可滑动列表,但是包含的滑动视图只有一个Controller控制,所以都会跟着手势向同一个反向滑动

Flutter中提出一个Sliver(中文为“薄片”的意思)概念,如果一个可滚动组件支持Sliver模型,那么该滚动可以将子组件分成好多个“薄片”(Sliver),只有当Sliver出现在视口中时才会去构建它,这种模型也称为“基于Sliver的延迟构建模型”。
可滚动组件中有很多都支持基于Sliver的延迟构建模型,如ListView、GridView,但是也有不支持该模型的,如SingleChildScrollView.

这个跟安卓的思维是一致的,类似与分页加载,复用加载,数据量比较大的时候对提高加载效率非常有帮助。SingleChildScrollView只包含一个子widget,本身也只适用于子widget数量有限的场景。

对上面的 AppBar 部分进行高度设置

CustomScrollView里添加的子widget都必须是Sliver,比如添加Image或者Text都会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: PreferredSize(
preferredSize:
Size.fromHeight(MediaQueryData.fromWindow(window).padding.top),
child: SafeArea(
top: true,
child: Offstage(),
),
),
body: CustomScrollViewWidget(),
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class CustomScrollViewWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
CustomScrollView它有一个Slivers[],可容纳很多孩子
return CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[

第一个孩子,SliverAppBar是一个可伸缩的appbar
SliverAppBar(
pinned: false,

//下拉时的伸缩大小
expandedHeight: 250.0,

backgroundColor: Colors.blue,

//伸缩的填充图片
flexibleSpace: FlexibleSpaceBar(
background: Image.network("http://b-ssl.duitang.com/uploads/blog/201312/04/20131204184148_hhXUT.jpeg",fit: BoxFit.cover,),
),
),

<font color="red">第二个孩子,SliverFixedExtentList是一个列表,相当于ListView</font>
SliverFixedExtentList(
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
color: Colors.red,
alignment: Alignment.center,
child: Text("$index"),
);
}, childCount: 20),
itemExtent: 50),

<font color="red">第三个孩子,SliverAppBar是一个可伸缩的appbar</font>
SliverAppBar(
pinned: false,
expandedHeight: 250.0,
backgroundColor: Colors.blue,
flexibleSpace: FlexibleSpaceBar(
background: Image.network("http://b-ssl.duitang.com/uploads/blog/201312/04/20131204184148_hhXUT.jpeg",fit: BoxFit.cover,),
),
),
],
);
}
}

SliverAppBar 的分析


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const SliverAppBar({
Key key,
this.leading,//左侧的图标或文字,多为返回箭头
this.automaticallyImplyLeading = true,//没有leading为true的时候,默认返回箭头,没有leading且为false,则显示title
this.title,//标题
this.actions,//标题右侧的操作
this.flexibleSpace,//可以理解为SliverAppBar的背景内容区
this.bottom,//SliverAppBar的底部区
this.elevation,//阴影
this.forceElevated = false,//是否显示阴影
this.backgroundColor,//背景颜色
this.brightness,//状态栏主题,默认Brightness.dark,可选参数light,可改变手机状态栏颜色
this.iconTheme,//SliverAppBar图标主题
this.actionsIconTheme,//action图标主题
this.textTheme,//文字主题
this.primary = true,//是否显示在状态栏的下面,false就会占领状态栏的高度
this.centerTitle,//标题是否居中显示
this.titleSpacing = NavigationToolbar.kMiddleSpacing,//标题横向间距
this.expandedHeight,//合并的高度,默认是状态栏的高度加AppBar的高度
this.floating = false,//滑动时是否悬浮
this.pinned = false,//标题栏是否固定
this.snap = false,//配合floating使用
})
其中比较常用的leading,title,actions,backgroundColor,flexibleSpace,pinned,expandedHeight

因为CustomScrollView子widget必须是Sliver,但是换个思路,gradview和listview的子widget没有这个限制,是否以此作为多type实现的方式呢?

我实验了一下是可以的,由此可以断言,CustomScrollView可以完全实现Android多type布局的效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class CustomScrollViewWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[
SliverAppBar(
leading: IconButton(icon: Icon(Icons.arrow_back), onPressed: () {}),
title: Text("标题"),
actions: <Widget>[
IconButton(icon: Icon(Icons.share), onPressed: () {})
],
primary: true,
pinned: true,
centerTitle: true,
expandedHeight: 250.0,
backgroundColor: Colors.blue,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
"http://b-ssl.duitang.com/uploads/blog/201312/04/20131204184148_hhXUT.jpeg",
fit: BoxFit.cover,
),
),
),
SliverFixedExtentList(
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
color: Colors.deepPurpleAccent,
alignment: Alignment.center,
child: Text("这只是中间type"),
);
}, childCount: 1),
itemExtent: 60),
SliverPadding(
padding: EdgeInsets.all(20),
sliver: SliverGrid(
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
color: index % 2 == 0 ? Colors.greenAccent : Colors.yellow,
alignment: Alignment.center,
child: Text("$index"),
);
}, childCount: 8),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
childAspectRatio: 1)),
),
SliverFixedExtentList(
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
height: 30,
color: index % 2 == 0 ? Colors.red : Colors.purpleAccent,
alignment: Alignment.center,
child: Text("$index"),
);
}, childCount: 20),
itemExtent: 50),
SliverFixedExtentList(
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
color: Colors.deepPurpleAccent,
alignment: Alignment.center,
child: Text("这只是一个footer"),
);
}, childCount: 1),
itemExtent: 60),
SliverFixedExtentList(
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
child: Image.network(
"http://b-ssl.duitang.com/uploads/item/201208/08/20120808125749_UxUu8.jpeg",
height: 60,
fit: BoxFit.fitWidth,
),
);
}, childCount: 1),
itemExtent: 60),
],
);
}
}
  • Title: CupertinoPageScaffold、CustomScrollView
  • Author: 人间烟火/张佳伟版
  • Created at: 2024-04-22 18:02:16
  • Updated at: 2024-04-25 22:44:17
  • Link: https://945912035.github.io/2024/04/22/2024-4-22/
  • License: This work is licensed under CC BY-NC-SA 4.0.
 Comments
On this page
CupertinoPageScaffold、CustomScrollView