import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:zhiying_base_widget/pages/invited_friends/invited_friends_bloc.dart'; import 'package:zhiying_base_widget/pages/invited_friends/models/invite_friend_data_model.dart'; import 'package:zhiying_base_widget/pages/invited_friends/models/invited_friends_model.dart'; import 'package:zhiying_base_widget/template/invited_friend_template/invited_friend_template_creater.dart'; import 'package:zhiying_base_widget/widgets/empty/empty_widget.dart'; import 'package:zhiying_base_widget/widgets/share/models/share_data_model.dart'; import 'package:zhiying_base_widget/widgets/share/share_alert.dart'; import 'package:zhiying_comm/util/base_bloc.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; // 邀请好友 class InvitedFriendsPage extends StatefulWidget { final Map model; const InvitedFriendsPage(this.model, {Key key}) : super(key: key); @override _InvitedFriendsPageState createState() => _InvitedFriendsPageState(); } class _InvitedFriendsPageState extends State { @override Widget build(BuildContext context) { return BlocProvider( bloc: InvitedFriendshBloc(), child: _InvitedFriendsContainer(widget.model), ); } } class _InvitedFriendsContainer extends StatefulWidget { final Map data; const _InvitedFriendsContainer(this.data, {Key key}) : super(key: key); @override _InvitedFriendsContainerState createState() => _InvitedFriendsContainerState(); } class _InvitedFriendsContainerState extends State<_InvitedFriendsContainer> { InvitedFriendshBloc _bloc; InvitedFriendsModel _model; int _currentIndex = 0; // 邀请海报下标 List _contentKeys; SwiperController _controller; @override void initState() { _bloc = BlocProvider.of(context); _bloc.loadData(widget.data['skip_identifier']); _controller = SwiperController(); super.initState(); } @override void dispose() { _controller?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return StreamBuilder( stream: _bloc.outData, builder: (BuildContext context, AsyncSnapshot snapshot) { _model = snapshot.data; _contentKeys = List.generate( _model?.dataModel?.posterList?.length ?? 0, (index) => GlobalKey()); var posters = List.generate( _model?.dataModel?.posterList?.length ?? 0, (index) { return InvitedFriendsTemp( _model.dataModel.posterList[index], _contentKeys[index]); }); return Scaffold( appBar: _createNav(), body: _model == null ? Container() : Stack( children: [ Container( width: double.infinity, height: double.infinity, child: CachedNetworkImage( imageUrl: _model?.bgImg ?? '', fit: BoxFit.cover, ), ), Column( children: [ Expanded( child: _createSwiper(posters), ), _createTeacher(), _createBottom(), ], ), ], ), ); }); } // 导航栏 Widget _createNav() { return CupertinoNavigationBar( border: Border( bottom: BorderSide( width: 0.0, // One physical pixel. style: BorderStyle.none, ), ), backgroundColor: HexColor.fromHex(_model?.appBarBgColor ?? '#ffffff'), leading: Navigator.canPop(context) ? GestureDetector( child: Container( padding: EdgeInsets.zero, child: Icon( Icons.arrow_back_ios, size: 20, ), ), onTap: () { if (Navigator.canPop(context)) { Navigator.pop(context); } }, ) : Container(), middle: Text( _model?.appBarName ?? '邀请好友', style: TextStyle( fontSize: 15, color: HexColor.fromHex(_model?.appBarNameColor ?? '#333333'), ), ), trailing: Text( _model?.appBarRightBtnText ?? '规则', style: TextStyle( fontSize: 15, color: HexColor.fromHex(_model?.appBarRightBtnTextColor ?? '#333333'), ), ), ); } Widget _createSwiper(List posters) { if ((_model?.dataModel?.posterList?.length ?? 0) <= 0) { return Container( margin: EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 20), width: double.infinity, child: EmptyWidget(), color: Colors.white, ); } return Container( width: double.infinity, child: Swiper( controller: _controller, onIndexChanged: (index) { _currentIndex = index; }, itemBuilder: (BuildContext context, int index) { return posters[index]; }, itemCount: posters.length, viewportFraction: 0.7, scale: 0.9, ), ); } Widget _createTeacher() { if (_model.wechatTip == null) { return Container(); } InvitedWechatTeacherSkipModel skipModel; // 是否绑定微信导师 if (_model.dataModel.isBindTeacher == '1') { skipModel = _model.wechatTip.toWechatTeacher; } else { skipModel = _model.wechatTip.toInputWechatUsername; } return Container( width: double.infinity, margin: EdgeInsets.only(top: 20, left: 30, right: 30), padding: EdgeInsets.only(left: 13, right: 3), height: 36, decoration: BoxDecoration( color: Color(0x80ffffff), borderRadius: BorderRadius.circular(18), ), child: Row( children: [ Container( margin: EdgeInsets.only(right: 10), width: 18, height: 18, child: CachedNetworkImage(imageUrl: _model?.wechatTip?.icon ?? '')), Expanded( child: Text( skipModel.tipText ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 13, color: HexColor.fromHex(skipModel.tipTextColor ?? '#333333'), ), ), ), GestureDetector( onTap: () { RouterUtil.route(skipModel, skipModel.toJson(), context); }, child: Container( width: 88, height: 30, decoration: BoxDecoration( color: HexColor.fromHex( _model?.wechatTip?.btnBgColor ?? '#ffffff'), borderRadius: BorderRadius.circular(15)), child: Center( child: Text( skipModel?.btnText ?? '', style: TextStyle( fontSize: 13, color: HexColor.fromHex( _model?.wechatTip?.btnTextColor ?? '#333333'), ), ), ), ), ), ], ), ); } Widget _createBottom() { return SafeArea( top: false, child: Container( margin: EdgeInsets.all(12.5), padding: EdgeInsets.all(10), width: double.infinity, decoration: BoxDecoration( color: HexColor.fromHex(_model?.bottom?.bgColor ?? '#ffffff'), borderRadius: BorderRadius.circular(18), boxShadow: [ BoxShadow( offset: Offset(0, 5), //x,y轴 color: Colors.black12.withOpacity(0.1), //投影颜色 blurRadius: 10 //,投影距离 ) ], ), child: Column( children: [ Row( children: List.generate(_model?.bottom?.btns?.length ?? 0, (index) { InvitedFriendsButtonModel model = _model.bottom.btns[index]; return Expanded( child: GestureDetector( onTap: () { _onButtonTap(model.type ?? ''); }, child: Container( margin: EdgeInsets.only(left: 8, right: 8), height: 28, decoration: BoxDecoration( color: HexColor.fromHex(model?.bgColor ?? ''), borderRadius: BorderRadius.circular(14), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( margin: EdgeInsets.only(right: 2), width: 12, height: 12, child: CachedNetworkImage( imageUrl: model?.icon ?? '', ), ), Text( model?.text, style: TextStyle( color: HexColor.fromHex( model?.textColor ?? '#ffffff'), fontSize: 13), ), ], ), ), ), ); }), ), _model?.bottom?.tipText == null || _model?.bottom?.tipText == '' ? Container() : Padding( padding: EdgeInsets.only(top: 10), child: Text( _model?.bottom?.tipText ?? '', style: TextStyle( fontSize: 13, color: HexColor.fromHex( _model?.bottom?.tipTextColor ?? '#999999')), ), ), ], ), ), ); } // 底部按钮点击 void _onButtonTap(String type) { if (_currentIndex >= (_model?.dataModel?.posterList?.length ?? 0)) { Fluttertoast.showToast(msg: '分享失败,暂无选中海报'); return; } InvitedFriendsPosterDataModel poster = _model.dataModel.posterList[_currentIndex]; if (type == 'copy_link') { //复制链接 if (_model?.dataModel?.inviteLink != null && _model.dataModel.inviteLink.length > 0) { Fluttertoast.showToast(msg: '复制成功'); Clipboard.setData(ClipboardData(text: _model.dataModel.inviteLink)); } } else if (type == 'share_poster') { //分享海报 GlobalKey key = _contentKeys[_currentIndex]; _sharePoster(key); } else if (type == 'copy_invite_code') { //复制邀请码 if (poster?.inviteCode != null && poster.inviteCode != '') { Fluttertoast.showToast(msg: '复制成功'); Clipboard.setData(ClipboardData(text: poster.inviteCode)); } } } // 生成海报分享 void _sharePoster(GlobalKey key) async { BuildContext buildContext = key.currentContext; if (null != buildContext) { RenderRepaintBoundary boundary = buildContext.findRenderObject(); ui.Image image = await boundary.toImage(pixelRatio: 2.0); // 注意:png是压缩后格式,如果需要图片的原始像素数据,请使用rawRgba ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png); Uint8List pngBytes = byteData.buffer.asUint8List(); ShareDataModel shareModel = ShareDataModel(poster: pngBytes); _showShareAlert(shareModel); } } // 弹出分享框 void _showShareAlert(ShareDataModel shareModel) async { showCupertinoModalPopup( context: context, builder: (context) => ShareAlert( shareModel, 'pub.flutter.share_icon', // child: GoodsShareAlertContent(), ), ); } } class InvitedFriendsTemp extends StatefulWidget { final InvitedFriendsPosterDataModel dataModel; final GlobalKey contentKey; const InvitedFriendsTemp(this.dataModel, this.contentKey, {Key key}) : super(key: key); @override _InvitedFriendsTempState createState() => _InvitedFriendsTempState(); } class _InvitedFriendsTempState extends State { double _scale = 0; @override void initState() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) { double scaleW = context.size.height / 667; double scaleH = context.size.width / 375; double scale = scaleH < scaleW ? scaleH : scaleW; if (scale != _scale) { setState(() { _scale = scale; }); } Logger.debug('${context.size.height} ${context.size.width} ${_scale}'); }); super.initState(); } @override Widget build(BuildContext context) { return Transform.scale( scale: _scale, child: InvitedFriendTemplateCreater.create( widget.dataModel, widget.contentKey)); } }