我们在上一章回中介绍了"如何绘制阴影效果"相关的内容,本章回中将介绍如何自定义一个可以滑动的刻度尺.闲话休提,让我们一起Talk Flutter吧。
任何优美的文字在图形面前都显得苍白无力,因此我们先先上效果图。图中演示了一个可以滑动的刻度尺,图形中左侧的文字表示刻度值,右侧蓝色的线条表示刻度线,
刻度线上的圆脸图标表示滑动条,它可以在刻度线上滑动,滑动时左侧的刻度值会发生变化。我们将在本章回中介绍如何去实现图片中的刻度尺效果。
实现图中的效果需要使用自定义组件相关的知识,详细内容可以查看我们前面的博客。我们先把上面图片的内容做一个拆分:左侧显示刻度值的文本使用Text来实现,滑
块是一个图片,使用Iamge或者Icon来实现。刻度尺可以通过Container来实现,或者通过CustomPainter来绘制。滑动滑块是一个手势动作,通过手势组件来实现。
通过拆分后就会发现原来看着很复杂的效果一下子变成了常用的组件。拆分后的内容还需要进行组装,这样才能组成一个完整的组件,组装这些内容可以通过stack组件来
实现。上面描述的这些内容就是我们实现滑动刻度尺的思路,看似复杂的滑动刻度尺效果就在这一拆一合之间实现了,是不是感觉很优美?
有了实现的思路就有了大体的目标和方向,接下来我们就一步一个脚印地朝着目标方向前进。这一个个的脚印就是具体的实现方法:
GestureDetector(
child: Container(
color: Colors.black12,
width: widget.width,
height: widget.height,
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
left: textLeft,
top: textTop,
child: Text("${_currentValue.toInt().toString().padLeft(2, "0")} : 00"),
),
Positioned(
left: rulerLeft,
top: rulerTop,
///整个刻度尺
child: Container(
///控制刻度尺右侧的线
decoration: const BoxDecoration(
color: Colors.transparent,
border:Border(
right: BorderSide(color: Colors.black,width: 2,),
),
),
///整个刻度尺的长度和宽度
width: ruleWidth,
height: ruleHeight,
///使用ListView的divider来充当刻度线
child: ListView(
controller: scrollController,
///通过List中item的高度控制刻度线之间的间隔
itemExtent: space,
children: List.generate(lineCount, (index) {
if(index %2 != 0 ) {
return Container(
///这个颜色需要和整个组件的背景颜色一样,或者做成透明色
color: Colors.transparent,
child: const SizedBox.shrink(),
);
}else {
return const Divider(
///线的宽度
thickness: lineHeight,
///总宽度减去此值为线的长度
indent: lineWidth,
color: Colors.blue,
);
}
}),
),
),
),
///滑块
Positioned(
top: value,
left: thumbLeft,
child: Container(
color: Colors.transparent,
child: const Icon(Icons.face,color: Colors.redAccent,),
), ),
],
),
),
onPanUpdate: (event) {
setState(() {
value += event.delta.dy;
_currentValue = value;
///转换滑动值为刻度值,
});
},
);
上面的示例代码中完整地演示了整个实现方法中的内容,不过还有一些细节需要说明:每个子组件的位置都是通完Ponsitioned组件控制的,具体的位置值也就是代码中
的top和left的数值可以自行指定,只要不超过外层组件大小就可以;ListView中每个项目的内容不重要,代码中设置了一个空组件,重要的是它的颜色,需要和组件
的背景颜色一致,或者指定成透明色。滑动的内容我们指定成了Icon,也可以指定成Image,或者设置成Widget,通过参数来设置Widget的内容;
最后,我们对本章回的内容做一个全面的总结,同时给大家分享一些经验: