flutter - 点击事件(二) - 给图片增加点击UI效果

文章目录


flutter 中 如果给图片外面套 InkWell ,你会发现点击的逻辑生效了,但是 UI 上没反应

备注: , 违反版权请联系我,删除

p

代码如下

 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 来实现

在按下的时候执行动画, 然后在抬起或取消的时候也先不结束动画,而是监听动画状态,等待动画完成再执行动画效果上的取消动画

后记

点击效果相关的简单实现就在这里了,有不明白的可以留言哦