上一篇, 介绍了如何便利的构造一个自己的点击控件
flutter 中 如果给图片外面套 InkWell ,你会发现点击的逻辑生效了,但是 UI 上没反应
备注: 图片来源, 违反版权请联系我,删除
代码如下
import 'package:flutter/material.dart';
class ImageTapWidget extends StatefulWidget {
final Widget child;
final Function onTap;
const ImageTapWidget({Key key, this.child, this.onTap}) : super(key: key);
@override
ImageTapWidgetState createState() {
return new ImageTapWidgetState();
}
}
class ImageTapWidgetState extends State<ImageTapWidget> {
var isDown = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
child: AnimatedContainer(
duration: Duration(milliseconds: 500),
foregroundDecoration: BoxDecoration(
color: isDown ? Colors.white.withOpacity(0.5) : Colors.transparent,
),
child: widget.child,
),
onTap: widget.onTap,
onTapDown: (d) => setState(() => this.isDown = true),
onTapUp: (d) => setState(() => this.isDown = false),
onTapCancel: () => setState(() => this.isDown = false),
);
}
}
利用 Container 的前景色完成点击色的变化
利用 AnimatedContainer 完成颜色的过度
这样就完成了一个有点击效果的控件,当然这个控件的效果不止于对图片有效,对所有的控件都有效,但是正常来说我对于其他类型的控件应该不需要做这个操作
当然,有的时候你会遇到点击和松开之间过快,造成了视觉上没点击的感觉,这种情况下可以使用另一种方法,利用动画的方式来实现
修改一下上面的类,替换为如下代码
import 'package:flutter/material.dart';
class ImageTapWidget extends StatefulWidget {
final Widget child;
final Function onTap;
const ImageTapWidget({Key key, this.child, this.onTap}) : super(key: key);
@override
ImageTapWidgetState createState() {
return new ImageTapWidgetState();
}
}
class ImageTapWidgetState extends State<ImageTapWidget> with SingleTickerProviderStateMixin {
AnimationController _ctl;
@override
void initState() {
super.initState();
_ctl = AnimationController(vsync: this, duration: Duration(milliseconds: 200));
}
@override
void dispose() {
_ctl.stop();
_ctl.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
child: AnimatedBuilder(
animation: _ctl,
builder: (BuildContext context, Widget child) {
return Container(
foregroundDecoration: BoxDecoration(
color: Colors.white.withOpacity(0.5 * _ctl.value),
),
child: widget.child,
);
},
),
onTap: widget.onTap,
onTapDown: (d) => _ctl.forward(),
onTapUp: (d) => prepareToIdle(),
onTapCancel: () => prepareToIdle(),
);
}
void prepareToIdle() {
AnimationStatusListener listener;
listener = (AnimationStatus statue) {
if (statue == AnimationStatus.completed) {
_ctl.removeStatusListener(listener);
toStart();
}
};
_ctl.addStatusListener(listener);
if (!_ctl.isAnimating) {
_ctl.removeStatusListener(listener);
toStart();
}
}
void toStart() {
_ctl.stop();
_ctl.reverse();
}
}
创建一个AnimationBuilder
结合 AnimationController
来实现
在按下的时候执行动画, 然后在抬起或取消的时候也先不结束动画,而是监听动画状态,等待动画完成再执行动画效果上的取消动画
点击效果相关的简单实现就在这里了,有不明白的可以留言哦