flutter - 点击事件(二) - 给图片增加点击UI效果
文章目录
flutter 中 如果给图片外面套 InkWell ,你会发现点击的逻辑生效了,但是 UI 上没反应
备注: 图片来源 , 违反版权请联系我,删除
代码如下
1import 'package:flutter/material.dart';
2
3class ImageTapWidget extends StatefulWidget {
4 final Widget child;
5 final Function onTap;
6
7 const ImageTapWidget({Key key, this.child, this.onTap}) : super(key: key);
8
9 @override
10 ImageTapWidgetState createState() {
11 return new ImageTapWidgetState();
12 }
13}
14
15class ImageTapWidgetState extends State<ImageTapWidget> {
16 var isDown = false;
17 @override
18 Widget build(BuildContext context) {
19 return GestureDetector(
20 child: AnimatedContainer(
21 duration: Duration(milliseconds: 500),
22 foregroundDecoration: BoxDecoration(
23 color: isDown ? Colors.white.withOpacity(0.5) : Colors.transparent,
24 ),
25 child: widget.child,
26 ),
27 onTap: widget.onTap,
28 onTapDown: (d) => setState(() => this.isDown = true),
29 onTapUp: (d) => setState(() => this.isDown = false),
30 onTapCancel: () => setState(() => this.isDown = false),
31 );
32 }
33}
利用 Container 的前景色完成点击色的变化
利用 AnimatedContainer 完成颜色的过度
这样就完成了一个有点击效果的控件,当然这个控件的效果不止于对图片有效,对所有的控件都有效,但是正常来说我对于其他类型的控件应该不需要做这个操作
点击效果过快
当然,有的时候你会遇到点击和松开之间过快,造成了视觉上没点击的感觉,这种情况下可以使用另一种方法,利用动画的方式来实现
1import 'package:flutter/material.dart';
2
3class ImageTapWidget extends StatefulWidget {
4 final Widget child;
5 final Function onTap;
6
7 const ImageTapWidget({Key key, this.child, this.onTap}) : super(key: key);
8
9 @override
10 ImageTapWidgetState createState() {
11 return new ImageTapWidgetState();
12 }
13}
14
15class ImageTapWidgetState extends State<ImageTapWidget> with SingleTickerProviderStateMixin {
16 AnimationController _ctl;
17
18 @override
19 void initState() {
20 super.initState();
21 _ctl = AnimationController(vsync: this, duration: Duration(milliseconds: 200));
22 }
23
24 @override
25 void dispose() {
26 _ctl.stop();
27 _ctl.dispose();
28 super.dispose();
29 }
30
31 @override
32 Widget build(BuildContext context) {
33 return GestureDetector(
34 child: AnimatedBuilder(
35 animation: _ctl,
36 builder: (BuildContext context, Widget child) {
37 return Container(
38 foregroundDecoration: BoxDecoration(
39 color: Colors.white.withOpacity(0.5 * _ctl.value),
40 ),
41 child: widget.child,
42 );
43 },
44 ),
45 onTap: widget.onTap,
46 onTapDown: (d) => _ctl.forward(),
47 onTapUp: (d) => prepareToIdle(),
48 onTapCancel: () => prepareToIdle(),
49 );
50 }
51
52 void prepareToIdle() {
53 AnimationStatusListener listener;
54 listener = (AnimationStatus statue) {
55 if (statue == AnimationStatus.completed) {
56 _ctl.removeStatusListener(listener);
57 toStart();
58 }
59 };
60 _ctl.addStatusListener(listener);
61 if (!_ctl.isAnimating) {
62 _ctl.removeStatusListener(listener);
63 toStart();
64 }
65 }
66
67 void toStart() {
68 _ctl.stop();
69 _ctl.reverse();
70 }
71}
创建一个AnimationBuilder
结合 AnimationController
来实现
在按下的时候执行动画, 然后在抬起或取消的时候也先不结束动画,而是监听动画状态,等待动画完成再执行动画效果上的取消动画
后记
点击效果相关的简单实现就在这里了,有不明白的可以留言哦