@@ -1,6 +1,21 @@ | |||||
import 'dart:typed_data'; | |||||
import 'dart:ui' as ui; | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:flutter/material.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: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/template/invited_friend_template/inviter_friend_template.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'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
// 邀请好友 | // 邀请好友 | ||||
@@ -16,22 +31,82 @@ class InvitedFriendsPage extends StatefulWidget { | |||||
class _InvitedFriendsPageState extends State<InvitedFriendsPage> { | class _InvitedFriendsPageState extends State<InvitedFriendsPage> { | ||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Scaffold( | |||||
appBar: _createNav(), | |||||
backgroundColor: Colors.redAccent, | |||||
body: Column( | |||||
children: <Widget>[ | |||||
Expanded( | |||||
child: _createSwiper(), | |||||
), | |||||
_createTeacher(), | |||||
_createBottom(), | |||||
], | |||||
), | |||||
return BlocProvider<InvitedFriendshBloc>( | |||||
bloc: InvitedFriendshBloc(), | |||||
child: _InvitedFriendsContainer(widget.model), | |||||
); | ); | ||||
} | } | ||||
} | |||||
class _InvitedFriendsContainer extends StatefulWidget { | |||||
final Map<String, dynamic> 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<GlobalKey> _contentKeys; | |||||
@override | |||||
void initState() { | |||||
_bloc = BlocProvider.of<InvitedFriendshBloc>(context); | |||||
_bloc.loadData(widget.data['skip_identifier']); | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return StreamBuilder<InvitedFriendsModel>( | |||||
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: <Widget>[ | |||||
Container( | |||||
width: double.infinity, | |||||
height: double.infinity, | |||||
child: CachedNetworkImage( | |||||
imageUrl: _model?.bgImg ?? '', | |||||
fit: BoxFit.cover, | |||||
), | |||||
), | |||||
Column( | |||||
children: <Widget>[ | |||||
Expanded( | |||||
child: _createSwiper(posters), | |||||
), | |||||
_createTeacher(), | |||||
_createBottom(), | |||||
], | |||||
), | |||||
], | |||||
), | |||||
); | |||||
}); | |||||
} | |||||
// 导航栏 | |||||
Widget _createNav() { | Widget _createNav() { | ||||
return CupertinoNavigationBar( | return CupertinoNavigationBar( | ||||
border: Border( | border: Border( | ||||
@@ -40,7 +115,7 @@ class _InvitedFriendsPageState extends State<InvitedFriendsPage> { | |||||
style: BorderStyle.none, | style: BorderStyle.none, | ||||
), | ), | ||||
), | ), | ||||
backgroundColor: Colors.white, | |||||
backgroundColor: HexColor.fromHex(_model?.appBarBgColor ?? '#ffffff'), | |||||
leading: Navigator.canPop(context) | leading: Navigator.canPop(context) | ||||
? GestureDetector( | ? GestureDetector( | ||||
child: Container( | child: Container( | ||||
@@ -58,40 +133,59 @@ class _InvitedFriendsPageState extends State<InvitedFriendsPage> { | |||||
) | ) | ||||
: Container(), | : Container(), | ||||
middle: Text( | middle: Text( | ||||
'邀请好友', | |||||
_model?.appBarName ?? '邀请好友', | |||||
style: TextStyle( | style: TextStyle( | ||||
fontSize: 15, | fontSize: 15, | ||||
color: HexColor.fromHex('#333333'), | |||||
color: HexColor.fromHex(_model?.appBarNameColor ?? '#333333'), | |||||
), | ), | ||||
), | ), | ||||
trailing: Text( | trailing: Text( | ||||
'规则', | |||||
_model?.appBarRightBtnText ?? '规则', | |||||
style: TextStyle( | style: TextStyle( | ||||
fontSize: 15, | fontSize: 15, | ||||
color: HexColor.fromHex('#333333'), | |||||
color: HexColor.fromHex(_model?.appBarRightBtnTextColor ?? '#333333'), | |||||
), | ), | ||||
), | ), | ||||
); | ); | ||||
} | } | ||||
Widget _createSwiper() { | |||||
Widget _createSwiper(List<Widget> 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( | return Container( | ||||
width: double.infinity, | width: double.infinity, | ||||
child: Swiper( | child: Swiper( | ||||
onIndexChanged: (index) { | |||||
_currentIndex = index; | |||||
}, | |||||
itemBuilder: (BuildContext context, int index) { | itemBuilder: (BuildContext context, int index) { | ||||
return new Image.network( | |||||
"http://via.placeholder.com/288x188", | |||||
fit: BoxFit.fill, | |||||
); | |||||
return posters[index]; | |||||
}, | }, | ||||
itemCount: 10, | |||||
viewportFraction: 0.8, | |||||
itemCount: posters.length, | |||||
viewportFraction: 0.7, | |||||
scale: 0.9, | scale: 0.9, | ||||
), | ), | ||||
); | ); | ||||
} | } | ||||
Widget _createTeacher() { | 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( | return Container( | ||||
width: double.infinity, | width: double.infinity, | ||||
margin: EdgeInsets.only(top: 20, left: 30, right: 30), | margin: EdgeInsets.only(top: 20, left: 30, right: 30), | ||||
@@ -104,33 +198,41 @@ class _InvitedFriendsPageState extends State<InvitedFriendsPage> { | |||||
child: Row( | child: Row( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Container( | Container( | ||||
margin: EdgeInsets.only(right: 10), | |||||
width: 18, | |||||
height: 18, | |||||
color: Colors.redAccent, | |||||
), | |||||
margin: EdgeInsets.only(right: 10), | |||||
width: 18, | |||||
height: 18, | |||||
child: | |||||
CachedNetworkImage(imageUrl: _model?.wechatTip?.icon ?? '')), | |||||
Expanded( | Expanded( | ||||
child: Text( | child: Text( | ||||
'联系导师教你更多赚钱秘籍', | |||||
skipModel.tipText ?? '', | |||||
maxLines: 1, | maxLines: 1, | ||||
overflow: TextOverflow.ellipsis, | overflow: TextOverflow.ellipsis, | ||||
style: TextStyle( | style: TextStyle( | ||||
fontSize: 13, | fontSize: 13, | ||||
color: Color(0xff333333), | |||||
color: HexColor.fromHex(skipModel.tipTextColor ?? '#333333'), | |||||
), | ), | ||||
), | ), | ||||
), | ), | ||||
Container( | |||||
width: 88, | |||||
height: 30, | |||||
decoration: BoxDecoration( | |||||
color: Colors.white, borderRadius: BorderRadius.circular(15)), | |||||
child: Center( | |||||
child: Text( | |||||
'联系导师', | |||||
style: TextStyle( | |||||
fontSize: 13, | |||||
color: Color(0xff333333), | |||||
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'), | |||||
), | |||||
), | ), | ||||
), | ), | ||||
), | ), | ||||
@@ -148,7 +250,7 @@ class _InvitedFriendsPageState extends State<InvitedFriendsPage> { | |||||
padding: EdgeInsets.all(10), | padding: EdgeInsets.all(10), | ||||
width: double.infinity, | width: double.infinity, | ||||
decoration: BoxDecoration( | decoration: BoxDecoration( | ||||
color: Colors.white, | |||||
color: HexColor.fromHex(_model?.bottom?.bgColor ?? '#ffffff'), | |||||
borderRadius: BorderRadius.circular(18), | borderRadius: BorderRadius.circular(18), | ||||
boxShadow: [ | boxShadow: [ | ||||
BoxShadow( | BoxShadow( | ||||
@@ -161,29 +263,156 @@ class _InvitedFriendsPageState extends State<InvitedFriendsPage> { | |||||
child: Column( | child: Column( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Row( | Row( | ||||
children: List.generate(3, (index) { | |||||
children: | |||||
List.generate(_model?.bottom?.btns?.length ?? 0, (index) { | |||||
InvitedFriendsButtonModel model = _model.bottom.btns[index]; | |||||
return Expanded( | return Expanded( | ||||
child: Container( | |||||
margin: EdgeInsets.only(left: 8, right: 8), | |||||
height: 28, | |||||
decoration: BoxDecoration( | |||||
color: Colors.redAccent, | |||||
borderRadius: BorderRadius.circular(14), | |||||
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: <Widget>[ | |||||
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), | |||||
), | |||||
], | |||||
), | |||||
), | ), | ||||
), | ), | ||||
); | ); | ||||
}), | }), | ||||
), | ), | ||||
Padding( | |||||
padding: EdgeInsets.only(top: 10), | |||||
child: Text( | |||||
'您的好友下载APP并使用的您的邀请码成功登录之后,Ta将成为您的粉丝,粉丝下单,您也可以获得收益哦!', | |||||
style: TextStyle(fontSize: 13, color: Color(0xff999999)), | |||||
), | |||||
), | |||||
_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<InvitedFriendsTemp> { | |||||
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)); | |||||
} | |||||
} | } |
@@ -0,0 +1,55 @@ | |||||
import 'dart:async'; | |||||
import 'dart:convert' as convert; | |||||
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_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class InvitedFriendshBloc extends BlocBase { | |||||
InvitedFriendsModel _model; | |||||
StreamController<InvitedFriendsModel> _dataController = | |||||
StreamController<InvitedFriendsModel>(); | |||||
Stream<InvitedFriendsModel> get outData => _dataController.stream; | |||||
@override | |||||
void dispose() { | |||||
_dataController.close(); | |||||
_dataController = null; | |||||
} | |||||
void loadData(String skipIdentifier) async { | |||||
Map<String, dynamic> data = | |||||
await NetUtil.post('/api/v1/user/invitefriend', method: NetMethod.GET); | |||||
InvitedFriendsDataModel dataModel = InvitedFriendsDataModel.fromJson( | |||||
Map<String, dynamic>.from(data['data'])); | |||||
NetUtil.request('/api/v1/mod/${skipIdentifier.toString()}', | |||||
method: NetMethod.GET, onCache: (data) {}, onSuccess: (data) { | |||||
_model = _loadData(data); | |||||
_model?.dataModel = dataModel; | |||||
_dataController.add(_model); | |||||
}); | |||||
} | |||||
InvitedFriendsModel _loadData(dynamic data) { | |||||
try { | |||||
Map<String, dynamic> json = Map<String, dynamic>.from(data); | |||||
if (json == null || json.length == 0) { | |||||
return null; | |||||
} | |||||
List mods = json['mod_list']; | |||||
if (mods.first != null) { | |||||
json = Map<String, dynamic>.from(mods.first); | |||||
String d = json['data']; | |||||
Map<String, dynamic> da = | |||||
Map<String, dynamic>.from(convert.jsonDecode(d)); | |||||
return InvitedFriendsModel.fromJson(da); | |||||
} | |||||
} catch (err) { | |||||
Logger.error(err); | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -0,0 +1,66 @@ | |||||
class InvitedFriendsDataModel { | |||||
String isBindTeacher; | |||||
List<InvitedFriendsPosterDataModel> posterList; | |||||
String inviteLink; | |||||
InvitedFriendsDataModel( | |||||
{this.isBindTeacher, this.posterList, this.inviteLink}); | |||||
InvitedFriendsDataModel.fromJson(Map<String, dynamic> json) { | |||||
isBindTeacher = json['is_bind_teacher']; | |||||
if (json['poster_list'] != null) { | |||||
posterList = new List<InvitedFriendsPosterDataModel>(); | |||||
json['poster_list'].forEach((v) { | |||||
posterList.add(new InvitedFriendsPosterDataModel.fromJson(v)); | |||||
}); | |||||
} | |||||
inviteLink = json['invite_link']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['is_bind_teacher'] = this.isBindTeacher; | |||||
if (this.posterList != null) { | |||||
data['poster_list'] = this.posterList.map((v) => v.toJson()).toList(); | |||||
} | |||||
data['invite_link'] = this.inviteLink; | |||||
return data; | |||||
} | |||||
} | |||||
class InvitedFriendsPosterDataModel { | |||||
String type; | |||||
String posterImg; | |||||
String avatar; | |||||
String qrCode; | |||||
String inviteCode; | |||||
String whiteOutlineImg; | |||||
InvitedFriendsPosterDataModel( | |||||
{this.type, | |||||
this.posterImg, | |||||
this.avatar, | |||||
this.qrCode, | |||||
this.inviteCode, | |||||
this.whiteOutlineImg}); | |||||
InvitedFriendsPosterDataModel.fromJson(Map<String, dynamic> json) { | |||||
type = json['type']; | |||||
posterImg = json['poster_img']; | |||||
avatar = json['avatar']; | |||||
qrCode = json['qr_code']; | |||||
inviteCode = json['invite_code']; | |||||
whiteOutlineImg = json['white_outline_img']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['type'] = this.type; | |||||
data['poster_img'] = this.posterImg; | |||||
data['avatar'] = this.avatar; | |||||
data['qr_code'] = this.qrCode; | |||||
data['invite_code'] = this.inviteCode; | |||||
data['white_outline_img'] = this.whiteOutlineImg; | |||||
return data; | |||||
} | |||||
} |
@@ -0,0 +1,229 @@ | |||||
import 'package:zhiying_base_widget/pages/invited_friends/models/invite_friend_data_model.dart'; | |||||
import 'package:zhiying_comm/models/base/skip_model.dart'; | |||||
class InvitedFriendsModel { | |||||
String appBarName; | |||||
String appBarNameColor; | |||||
String appBarBgImg; | |||||
String appBarBgColor; | |||||
String appBarRightBtnIcon; | |||||
String appBarRightBtnText; | |||||
String appBarRightBtnTextColor; | |||||
String bgColor; | |||||
String bgImg; | |||||
List<String> posterList; | |||||
String whiteOutlineImg; | |||||
InvitedWechatTeacherModel wechatTip; | |||||
InvitedFriendsBottomModel bottom; | |||||
InvitedFriendsDataModel dataModel; // 数据 | |||||
InvitedFriendsModel( | |||||
{this.appBarName, | |||||
this.appBarNameColor, | |||||
this.appBarBgImg, | |||||
this.appBarBgColor, | |||||
this.appBarRightBtnIcon, | |||||
this.appBarRightBtnText, | |||||
this.appBarRightBtnTextColor, | |||||
this.bgColor, | |||||
this.bgImg, | |||||
this.posterList, | |||||
this.whiteOutlineImg, | |||||
this.wechatTip, | |||||
this.bottom}); | |||||
InvitedFriendsModel.fromJson(Map<String, dynamic> json) { | |||||
appBarName = json['app_bar_name']; | |||||
appBarNameColor = json['app_bar_name_color']; | |||||
appBarBgImg = json['app_bar_bg_img']; | |||||
appBarBgColor = json['app_bar_bg_color']; | |||||
appBarRightBtnIcon = json['app_bar_right_btn_icon']; | |||||
appBarRightBtnText = json['app_bar_right_btn_text']; | |||||
appBarRightBtnTextColor = json['app_bar_right_btn_text_color']; | |||||
bgColor = json['bg_color']; | |||||
bgImg = json['bg_img']; | |||||
posterList = json['poster_list'].cast<String>(); | |||||
whiteOutlineImg = json['white_outline_img']; | |||||
wechatTip = json['wechat_tip'] != null | |||||
? new InvitedWechatTeacherModel.fromJson(json['wechat_tip']) | |||||
: null; | |||||
bottom = json['bottom'] != null | |||||
? new InvitedFriendsBottomModel.fromJson(json['bottom']) | |||||
: null; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['app_bar_name'] = this.appBarName; | |||||
data['app_bar_name_color'] = this.appBarNameColor; | |||||
data['app_bar_bg_img'] = this.appBarBgImg; | |||||
data['app_bar_bg_color'] = this.appBarBgColor; | |||||
data['app_bar_right_btn_icon'] = this.appBarRightBtnIcon; | |||||
data['app_bar_right_btn_text'] = this.appBarRightBtnText; | |||||
data['app_bar_right_btn_text_color'] = this.appBarRightBtnTextColor; | |||||
data['bg_color'] = this.bgColor; | |||||
data['bg_img'] = this.bgImg; | |||||
data['poster_list'] = this.posterList; | |||||
data['white_outline_img'] = this.whiteOutlineImg; | |||||
if (this.wechatTip != null) { | |||||
data['wechat_tip'] = this.wechatTip.toJson(); | |||||
} | |||||
if (this.bottom != null) { | |||||
data['bottom'] = this.bottom.toJson(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class InvitedWechatTeacherModel { | |||||
String icon; | |||||
String bgColor; | |||||
InvitedWechatTeacherSkipModel toWechatTeacher; | |||||
InvitedWechatTeacherSkipModel toInputWechatUsername; | |||||
String btnTextColor; | |||||
String btnBgColor; | |||||
InvitedWechatTeacherModel( | |||||
{this.icon, | |||||
this.bgColor, | |||||
this.toWechatTeacher, | |||||
this.toInputWechatUsername, | |||||
this.btnTextColor, | |||||
this.btnBgColor}); | |||||
InvitedWechatTeacherModel.fromJson(Map<String, dynamic> json) { | |||||
icon = json['icon']; | |||||
bgColor = json['bg_color']; | |||||
toWechatTeacher = json['to_wechat_teacher'] != null | |||||
? new InvitedWechatTeacherSkipModel.fromJson(json['to_wechat_teacher']) | |||||
: null; | |||||
toInputWechatUsername = json['to_input_wechat_username'] != null | |||||
? new InvitedWechatTeacherSkipModel.fromJson( | |||||
json['to_input_wechat_username']) | |||||
: null; | |||||
btnTextColor = json['btn_text_color']; | |||||
btnBgColor = json['btn_bg_color']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['icon'] = this.icon; | |||||
data['bg_color'] = this.bgColor; | |||||
if (this.toWechatTeacher != null) { | |||||
data['to_wechat_teacher'] = this.toWechatTeacher.toJson(); | |||||
} | |||||
if (this.toInputWechatUsername != null) { | |||||
data['to_input_wechat_username'] = this.toInputWechatUsername.toJson(); | |||||
} | |||||
data['btn_text_color'] = this.btnTextColor; | |||||
data['btn_bg_color'] = this.btnBgColor; | |||||
return data; | |||||
} | |||||
} | |||||
class InvitedWechatTeacherSkipModel extends SkipModel { | |||||
String type; | |||||
String btnText; | |||||
String tipText; | |||||
String tipTextColor; | |||||
InvitedWechatTeacherSkipModel({ | |||||
this.type, | |||||
this.btnText, | |||||
this.tipText, | |||||
this.tipTextColor, | |||||
}); | |||||
InvitedWechatTeacherSkipModel.fromJson(Map<String, dynamic> json) { | |||||
super.fromJson(json); | |||||
type = json['type']; | |||||
btnText = json['btn_text']; | |||||
tipText = json['tip_text']; | |||||
tipTextColor = json['tip_text_color']; | |||||
skipIdentifier = json['skip_identifier']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = super.toJson(); | |||||
data['type'] = this.type; | |||||
data['btn_text'] = this.btnText; | |||||
data['tip_text'] = this.tipText; | |||||
data['tip_text_color'] = this.tipTextColor; | |||||
data['skip_identifier'] = this.skipIdentifier; | |||||
return data; | |||||
} | |||||
} | |||||
class InvitedFriendsBottomModel { | |||||
String bgColor; | |||||
String tipText; | |||||
String tipTextColor; | |||||
List<InvitedFriendsButtonModel> btns; | |||||
InvitedFriendsBottomModel( | |||||
{this.bgColor, this.tipText, this.tipTextColor, this.btns}); | |||||
InvitedFriendsBottomModel.fromJson(Map<String, dynamic> json) { | |||||
bgColor = json['bg_color']; | |||||
tipText = json['tip_text']; | |||||
tipTextColor = json['tip_text_color']; | |||||
if (json['btns'] != null) { | |||||
btns = new List<InvitedFriendsButtonModel>(); | |||||
json['btns'].forEach((v) { | |||||
btns.add(new InvitedFriendsButtonModel.fromJson(v)); | |||||
}); | |||||
} | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['bg_color'] = this.bgColor; | |||||
data['tip_text'] = this.tipText; | |||||
data['tip_text_color'] = this.tipTextColor; | |||||
if (this.btns != null) { | |||||
data['btns'] = this.btns.map((v) => v.toJson()).toList(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class InvitedFriendsButtonModel { | |||||
String type; | |||||
String text; | |||||
String textColor; | |||||
String icon; | |||||
String bgColor; | |||||
String bgColorT; | |||||
String skipIdentifier; | |||||
InvitedFriendsButtonModel( | |||||
{this.type, | |||||
this.text, | |||||
this.textColor, | |||||
this.icon, | |||||
this.bgColor, | |||||
this.bgColorT, | |||||
this.skipIdentifier}); | |||||
InvitedFriendsButtonModel.fromJson(Map<String, dynamic> json) { | |||||
type = json['type']; | |||||
text = json['text']; | |||||
textColor = json['text_color']; | |||||
icon = json['icon']; | |||||
bgColor = json['bg_color']; | |||||
bgColorT = json['bg_color_t']; | |||||
skipIdentifier = json['skip_identifier']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['type'] = this.type; | |||||
data['text'] = this.text; | |||||
data['text_color'] = this.textColor; | |||||
data['icon'] = this.icon; | |||||
data['bg_color'] = this.bgColor; | |||||
data['bg_color_t'] = this.bgColorT; | |||||
data['skip_identifier'] = this.skipIdentifier; | |||||
return data; | |||||
} | |||||
} |
@@ -0,0 +1,118 @@ | |||||
import 'dart:convert' as convert; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/pages/invited_friends/models/invite_friend_data_model.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class InvitedFriendTemplate extends StatelessWidget { | |||||
final InvitedFriendsPosterDataModel dataModel; | |||||
final GlobalKey contentKey; | |||||
Widget _qrcode; | |||||
InvitedFriendTemplate(this.dataModel, {Key key, this.contentKey}) | |||||
: super(key: key) { | |||||
_qrcode = Image.memory(convert.base64Decode(dataModel?.qrCode)); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return OverflowBox( | |||||
maxHeight: double.infinity, | |||||
maxWidth: 375, //固定宽度,保证所以手机下生成的模板一致 | |||||
child: RepaintBoundary( | |||||
key: contentKey, // 用于导出模板样式的key | |||||
child: Container( | |||||
// 模板的内容 | |||||
width: 375, | |||||
height: 667, | |||||
child: Stack( | |||||
children: <Widget>[ | |||||
Container( | |||||
width: double.infinity, | |||||
height: double.infinity, | |||||
child: CachedNetworkImage( | |||||
imageUrl: dataModel?.posterImg ?? '', | |||||
fit: BoxFit.fill, | |||||
), | |||||
), | |||||
Center( | |||||
child: Column( | |||||
mainAxisAlignment: MainAxisAlignment.end, | |||||
children: <Widget>[ | |||||
Container( | |||||
width: 176, | |||||
height: 198, | |||||
// color: Colors.white, | |||||
decoration: BoxDecoration( | |||||
image: DecorationImage( | |||||
image: CachedNetworkImageProvider( | |||||
dataModel?.whiteOutlineImg ?? ''))), | |||||
child: Column( | |||||
children: <Widget>[ | |||||
Container( | |||||
margin: EdgeInsets.only(top: 4), | |||||
width: 24, | |||||
height: 24, | |||||
child: ClipRRect( | |||||
borderRadius: BorderRadius.circular(12), | |||||
child: CachedNetworkImage( | |||||
imageUrl: dataModel?.avatar ?? '', | |||||
), | |||||
), | |||||
), | |||||
Container( | |||||
margin: EdgeInsets.only(top: 4), | |||||
width: 154, | |||||
height: 154, | |||||
child: _qrcode, | |||||
) | |||||
], | |||||
), | |||||
), | |||||
Row( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
children: <Widget>[ | |||||
Container( | |||||
width: 100, | |||||
height: 0.5, | |||||
color: Colors.white, | |||||
), | |||||
Padding( | |||||
padding: const EdgeInsets.all(8.0), | |||||
child: Text( | |||||
'邀请码', | |||||
style: TextStyle(fontSize: 18, color: Colors.white), | |||||
), | |||||
), | |||||
Container( | |||||
width: 100, | |||||
height: 0.5, | |||||
color: Colors.white, | |||||
), | |||||
], | |||||
), | |||||
Container( | |||||
width: 176, | |||||
height: 40, | |||||
margin: EdgeInsets.only(top: 8, bottom: 40), | |||||
decoration: BoxDecoration( | |||||
color: Colors.white, | |||||
borderRadius: BorderRadius.circular(13)), | |||||
child: Center( | |||||
child: Text( | |||||
dataModel.inviteCode, | |||||
style: TextStyle( | |||||
fontSize: 22, fontWeight: FontWeight.bold), | |||||
)), | |||||
) | |||||
], | |||||
), | |||||
) | |||||
], | |||||
), | |||||
), | |||||
), | |||||
); | |||||
} | |||||
} |
@@ -0,0 +1,21 @@ | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/pages/invited_friends/models/invite_friend_data_model.dart'; | |||||
import 'package:zhiying_base_widget/template/invited_friend_template/invited_friend_template.dart'; | |||||
class InvitedFriendTemplateCreater { | |||||
static Widget create( | |||||
InvitedFriendsPosterDataModel model, GlobalKey contentKey) { | |||||
// 根据type,返回对应的模板,当前只有一个模板 | |||||
if (model.type == '0') { | |||||
return InvitedFriendTemplate( | |||||
model, | |||||
contentKey: contentKey, | |||||
); | |||||
} else { | |||||
return InvitedFriendTemplate( | |||||
model, | |||||
contentKey: contentKey, | |||||
); | |||||
} | |||||
} | |||||
} |