Flutter-ListWheelScrollView

ListWheelScrollView

和 ListView 类似,但是正如它的名字,它像个轮子,显示的时候有弧度。

这是官方的组件,并不需要引入第三方依赖包。

使用

它就像一个横放的圆柱,你只能看到前面这个面。能看到多少东西,取决于它的大小和你离它的位置。

可以使用 diameterRatio 改变它的圆面直径。你站在一个地方看圆柱,圆柱越大,你看那个面越不像弧面,能看到的东西就越多。就好像本来弯曲的书本,你让它不那么弯曲后,看到的就更多了吧。

可以使用 perspective 来决定你的透视位置。你离它越远,看到的东西越多。就像一张弯曲的纸上写着很多字,你贴近了看,只能看到几个字,拿远了看,就看得见一些弯曲后的字,总体上来说能看清的字变多了。

前者是在视野不变的情况下,让圆柱可视面能显示更多的东西。后者是让圆柱面显示的东西不变的情况下,自己去获得更大的视野,企图去看到更多东西。

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
class Checker extends StatelessWidget {
const Checker({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
//层叠布局,用一个阴影来标注当前选项
return Stack(
children: [
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child:ListWheelScrollView.useDelegate(
//固定距离滚动,这样可以刚好停留在一个选项上
physics: const FixedExtentScrollPhysics(),
//透视程度。0代表从无限远的地方观察圆柱,而1代表从无限近的地方观察,近到无法渲染
//可选择的范围是(0,0.01],隔得越远,弧线角度变化越不明显,看到的范围也就越大
perspective: 0.005,
//直径比,默认为2。可以代表这个圆柱截面圆的直径。
//在某个固定的地方观察圆柱,圆柱截面直径越大,角度变化越不明显。列表看起来越像直线,看的范围反而好像变大了。
diameterRatio: 1.2,
//每个选项的高度
itemExtent: 50,
//子选项构造器
childDelegate: ListWheelChildBuilderDelegate(
childCount: 13,
builder: (context,index)=>Hour(hour: index,)
)
),
),
SizedBox(
width: 100,
child: ListWheelScrollView.useDelegate(
physics: const FixedExtentScrollPhysics(),
perspective: 0.005,
diameterRatio: 1.2,
itemExtent: 50,
childDelegate: ListWheelChildBuilderDelegate(
childCount: 60,
builder: (context,index)=>Minute(minute: index)
)
),
),
SizedBox(
width: 100,
child: ListWheelScrollView.useDelegate(
physics: const FixedExtentScrollPhysics(),
perspective: 0.005,
diameterRatio: 1.2,
itemExtent: 50,
childDelegate: ListWheelChildBuilderDelegate(
childCount: 2,
builder: (context,index){
return AmPm(am: index==0);
}
)
),
)
],
),
),
Center(
child: Container(
decoration: BoxDecoration(
color: const Color.fromRGBO(255, 255, 255, 0.3),
borderRadius: BorderRadius.circular(24)
),
height: 50,
),
)
],
);
}
}

效果

image-20221029143240083