微信魔法聊天代码,猜猜微信啪一啪是怎么用Flutter实现的
微信魔法聊天代码,猜猜微信啪一啪是怎么用Flutter实现的其实主要用了一个动画,然后使用TweenSequence进行多组补间动画双击自己头像,会显示「你拍了拍自己」,只是双击用户信息是自己的情况下这样显示,这没什么特别的,但是请求失败情况下的文案没太能对上,仍然显示的是「对方可能不知道你拍了他」,猜测这个文案是写在客户端的,可能要改的话又得更新版本喽咱们尽量处理的跟微信官方客户端一模一样连续一直双击头像会发现,只有第一次会发送信息,剩下的双击只会触发客户端行为「头像抖动」,是做了防爆处理的。大概过 10s 左右后恢复,可以再次触发断网情况下,双击头像,会发现,自己先能看到 「拍一拍」,然后过了一段时间后,会出现「因网络原因,对方可能不知道你拍了他」。这就证明是先走客户端的渲染逻辑,然后再发的网络请求,网络不好的情况下应该会经过重试过程,如果最终还是失败,则显示网络原因失败的字样
最近这个啪一啪效果挺火的啊
群里经常有人啪;
介绍其实之前我就双击过头像,但并没任何效果,估计是当时把这个啪一啪消息隐藏了的,最近才放出来的,刚好看到,才开始实现。
关于进度目前只是先把具体的效果实现,估计过几天你看wechat_flutter项目的时候就有啪一啪消息体了,我的思路是新增消息体封装,或者把原有的进行修改,比如说文字消息体自定义下内容,然后显示的时候判断即可;
处理方式【本段来自Android_ZzT】咱们尽量处理的跟微信官方客户端一模一样
暴力连续 「啪一啪」连续一直双击头像会发现,只有第一次会发送信息,剩下的双击只会触发客户端行为「头像抖动」,是做了防爆处理的。大概过 10s 左右后恢复,可以再次触发
断网下「啪一啪」断网情况下,双击头像,会发现,自己先能看到 「拍一拍」,然后过了一段时间后,会出现「因网络原因,对方可能不知道你拍了他」。这就证明是先走客户端的渲染逻辑,然后再发的网络请求,网络不好的情况下应该会经过重试过程,如果最终还是失败,则显示网络原因失败的字样
啪自己双击自己头像,会显示「你拍了拍自己」,只是双击用户信息是自己的情况下这样显示,这没什么特别的,但是请求失败情况下的文案没太能对上,仍然显示的是「对方可能不知道你拍了他」,猜测这个文案是写在客户端的,可能要改的话又得更新版本喽
实现其实主要用了一个动画,然后使用TweenSequence进行多组补间动画
TweenSequence<double>([
//使用TweenSequence进行多组补间动画
TweenSequenceItem<double>(tween: Tween(begin: 0 end: 10) weight: 1)
TweenSequenceItem<double>(tween: Tween(begin: 10 end: 0) weight: 1)
TweenSequenceItem<double>(tween: Tween(begin: 0 end: -10) weight: 1)
TweenSequenceItem<double>(tween: Tween(begin: -10 end: 0) weight: 1)
])
然后封装成了个动画组件,组件调用了Transform来进行转动;
封装的那个组件继承了animatedWidget 然后调用了super把自定义的listenable 传了进去,
class AnimateWidget extends AnimatedWidget {
final Widget child;
AnimateWidget({Animation<double> animation this.child})
: super(listenable: animation);
@override
Widget build(BuildContext context) {
final Animation<double> animation = listenable;
var result = Transform(
transform: Matrix4.rotationZ(animation.value * pi / 180)
alignment: Alignment.bottomCenter
child: new ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5))
child: this.child
)
);
return result;
}
}
也算是非常简单。
代码所在位置封装之后的代码所在
/wechat_flutter/lib/ui/view/shake_view.dart
然后项目中头像调用啪一啪的地方在
/wechat_flutter/lib/ui/message_view/msg_avatar.dart
大家可以去看下具体是怎么调用和封装的;
封装后的代码import 'dart:math';
import 'package:flutter/material.dart';
/// 封装之后的拍一拍
class ShakeView extends StatefulWidget {
final Widget child;
ShakeView({
this.child
});
_ShakeViewState createState() => _ShakeViewState();
}
class _ShakeViewState extends State<ShakeView>
with SingleTickerProviderStateMixin {
Animation<double> animation;
Animationcontroller controller;
initState() {
super.initState();
controller = AnimationController(
duration: const Duration(milliseconds: 500) vsync: this);
animation = TweenSequence<double>([
//使用TweenSequence进行多组补间动画
TweenSequenceItem<double>(tween: Tween(begin: 0 end: 10) weight: 1)
TweenSequenceItem<double>(tween: Tween(begin: 10 end: 0) weight: 1)
TweenSequenceItem<double>(tween: Tween(begin: 0 end: -10) weight: 1)
TweenSequenceItem<double>(tween: Tween(begin: -10 end: 0) weight: 1)
]).animate(controller);
controller.forward();
}
Widget build(BuildContext context) {
return AnimateWidget(animation: animation child: widget.child);
}
dispose() {
controller.dispose();
super.dispose();
}
}
class AnimateWidget extends AnimatedWidget {
final Widget child;
AnimateWidget({Animation<double> animation this.child})
: super(listenable: animation);
@override
Widget build(BuildContext context) {
final Animation<double> animation = listenable;
var result = Transform(
transform: Matrix4.rotationZ(animation.value * pi / 180)
alignment: Alignment.bottomCenter
child: new ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5))
child: this.child
)
);
return result;
}
}
调用例子
这个child就是你要啪一啪之后抖动的widget内容
new ShakeView(
child: new Image.network(
'url'
height: 50
width: 50
fit: BoxFit.cover
)
)
项目地址
github:https://github.com/fluttercandies/wechat_flutter
若有需要Flutter资源,麻烦各位转发一下(可以帮助更多的人看到哦!),记得一定要关注 转发,然后私信@芜湖Android“Flutter”,即可回复免费下载的方式!!如果是需要Android开发进阶的资源,则可以私信“Android开发”领取。
以下是部分内容展示:
Flutter