Flutter高仿微信系列共59篇,从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。
效果图:
实现代码:
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/10/27 15:21 * Description : 二维码收款 */ class QRCodeReceive extends StatefulWidget { @override StatecreateState() => _QRCodeState(); } class _QRCodeState extends State with TickerProviderStateMixin{ String account = SpUtils.getString(CommonUtils.LOGIN_ACCOUNT); UserBean? _userBean; String? qrCode; //是否隐藏金额 bool isHideAmount = true; //设置返回的金额 //String setAmount = ""; UserBean? _fromUserBean; PaymentBean? _paymentBean; String qrBalance = ""; late Animation _animation; late AnimationController _controller; var baseEvent; @override void initState() { super.initState(); _initAnimator(); _initBaseEvent(); initUser(); } void _initAnimator(){ /// 动画控制器,动画持续时间5秒,可重复播放 _controller = AnimationController( duration: const Duration(seconds: 1), vsync: this, ); /// 缩小至 0.2倍大小,放大至3倍大小 非线性动画 _animation = Tween (begin: 1, end: 1.3).animate( CurvedAnimation( parent: _controller, curve: Curves.easeInCirc, ), ); _controller.addStatusListener((status) { if(status == AnimationStatus.completed){ _controller.reverse(); } }); } void _startAnimator(){ _controller.forward(); } void _initBaseEvent() async { baseEvent = eventBus.on ((baseBean) { //显示对方头像信息 if(baseEvent != null && baseBean.type == BaseEvent.TYPE_QRCODE_PAYMENT){ Map result = baseBean.result; _paymentBean = result['payment_bean'] as PaymentBean; _initFromUser(_paymentBean); } }); } void initUser() async { _fromUserBean = await UserRepository.getInstance().findUserByAccount(_paymentBean?.fromAccount??""); _userBean = await UserRepository.getInstance().findUserByAccount(account); _refreshQRCode(); } void _refreshQRCode(){ if(qrBalance == ""){ qrCode = CommonUtils.QR_RECEIVE_CODE + "0" + ":" + account; } else { qrCode = CommonUtils.QR_RECEIVE_CODE + qrBalance + ":" + account; } setState(() { }); } void _initFromUser(PaymentBean? _paymentBean) async { _fromUserBean = await UserRepository.getInstance().findUserByAccount(_paymentBean?.fromAccount??""); _startAnimator(); setState(() { }); } //设置金额 void _setAmount() async{ qrBalance = await Navigator.push(context, MaterialPageRoute(builder: (context) => QRCodeSetAmount())); isHideAmount = false; _refreshQRCode(); } @override void dispose() { super.dispose(); eventBus.off(baseEvent); _controller.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Container( width: double.infinity, height: double.infinity, color: Color(0xffFFD700), child: Column( children: [ topWidget(), qrcodeReceiveWidget(), userInfo(), ], ), ), ); } //顶部返回栏 Widget topWidget(){ double appBarHeight = AppManager.getInstance().getAppBarHeight(); double top = AppManager.getInstance().getTop(context); double height = appBarHeight + top; return Container( margin: EdgeInsets.only(left:12, top: top, right: 12), height: height, alignment: AlignmentDirectional.center, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ InkWell( onTap: (){ Navigator.pop(context); }, child: Icon(Icons.arrow_back_ios,color: Colors.white,size: 26,), ), Text("二维码收款", style: TextStyle(fontSize: 22, color: Colors.white, fontWeight: FontWeight.bold),), Text(""), ], ), ); } //向商家付款 Widget qrcodeReceiveWidget(){ return Container( margin: EdgeInsets.only(left: 12, top: 10, right: 12), width: double.infinity, height: AppManager.getInstance().getWidth(context), color: Colors.white, child: Stack( children: [ Positioned( left:8, top: 8, child: Row( children: [ CommonUtils.getBaseIconPng("wc_qrcode_receive_icon", width: 30, height: 30), SizedBox(width: 10,), Text("二维码收款", style: TextStyle(fontSize: 20, color: Color(0xFFFFD700)),), ], ), ), Positioned( left: 0, top: 50, right :0, child: Container( alignment: AlignmentDirectional.center, child: Text("无需加好友,扫收款码向我付钱", style: TextStyle(color: Colors.grey.shade600),), ), ), Positioned( left: 0, top: 80, right :0, child: Offstage( offstage: isHideAmount, child: Container( alignment: AlignmentDirectional.center, child: Text(qrBalance, style: TextStyle(fontSize: 26, color: Colors.black, fontWeight: FontWeight.bold),), ), ), ), Center( child: getQrWidget(), ), Positioned( left: 80, bottom: 50, child: InkWell( onTap: (){ _setAmount(); }, child: Text("设置金额", style: TextStyle(fontSize: 16, color: Colors.black),) ), ), Positioned( right: 80, bottom: 50, child: Text("保存收款码", style: TextStyle(fontSize: 16, color: Colors.black),) ), ], ), ); } //付款用户头像信息 Widget userInfo(){ return Offstage( offstage: _fromUserBean == null?true:false, child: Container( margin: EdgeInsets.only(left: 12, top: 10, right: 12), padding: EdgeInsets.only(bottom: 10), width: double.infinity, color: Colors.white, child: ScaleTransition( scale: _animation, child: Container( margin: EdgeInsets.only(left: 12, top:10, right: 22), child: Row( children: [ CommonAvatarView.showBaseImage(_fromUserBean?.avatar??""), SizedBox(width:10), Text(_fromUserBean?.nickName??"", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),), Expanded(child: Text("")), Text("¥${_paymentBean?.balance}", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), ], ), ), ), ), ); } //获取二维码图片 Widget getQrWidget(){ return QrImage( data: '${qrCode}', version: QrVersions.auto, size: 200, gapless: false, embeddedImage: CommonAvatarView.showQrImage(_userBean?.avatar??""), embeddedImageStyle: QrEmbeddedImageStyle( size: Size(38, 38), ), ); } }