| @@ -680,7 +680,7 @@ | |||
| "languageVersion": "2.1" | |||
| } | |||
| ], | |||
| "generated": "2020-09-15T02:01:44.342412Z", | |||
| "generated": "2020-09-15T07:31:12.840893Z", | |||
| "generator": "pub", | |||
| "generatorVersion": "2.7.2" | |||
| } | |||
| @@ -15,9 +15,8 @@ import 'package:zhiying_base_widget/widgets/others/normal_nav/normal_nav_creater | |||
| import 'package:zhiying_base_widget/widgets/wallet/wallet_data/wallet_data.dart'; | |||
| import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail.dart'; | |||
| import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| import 'package:zhiying_comm/util/defalut_widget_creater.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class BaseWidgetRegister { | |||
| /// 初始化方法 | |||
| @@ -52,6 +51,7 @@ class BaseWidgetRegister { | |||
| // /// 可滚动banner | |||
| WidgetFactory.regist('index_carousel', HomeSlideBannerCreater()); | |||
| WidgetFactory.regist('index_recommend_list', GoodsListCreater()); | |||
| /// 首页快速入口 | |||
| WidgetFactory.regist('home_quick_entry', HomeQuickEntryCreater()); | |||
| // | |||
| @@ -64,17 +64,26 @@ class BaseWidgetRegister { | |||
| // ==================== 个人中心 | |||
| WidgetFactory.regist('profile_appbar', MineNavCreater()); | |||
| WidgetFactory.regist('profile_background', DefaultWidgetCreater((model) => MineNavBg(model))); | |||
| WidgetFactory.regist('profile_header', DefaultWidgetCreater((model) => MineHeader(model))); | |||
| WidgetFactory.regist('profile_earning', DefaultWidgetCreater((model) => MineData())); | |||
| WidgetFactory.regist('profile_functions', DefaultWidgetCreater((model) => MineQuickEntry())); | |||
| WidgetFactory.regist('profile_my_functions', DefaultWidgetCreater((model) => MineQuickEntry())); | |||
| WidgetFactory.regist('profile_carousel', DefaultWidgetCreater((model) => HomeBannerWidget(model))); | |||
| WidgetFactory.regist('profile_background', | |||
| DefaultWidgetCreater((model) => MineNavBg(model))); | |||
| WidgetFactory.regist( | |||
| 'profile_header', DefaultWidgetCreater((model) => MineHeader(model))); | |||
| WidgetFactory.regist( | |||
| 'profile_earning', DefaultWidgetCreater((model) => MineData(model))); | |||
| WidgetFactory.regist( | |||
| 'profile_functions', DefaultWidgetCreater((model) => MineQuickEntry())); | |||
| WidgetFactory.regist('profile_my_functions', | |||
| DefaultWidgetCreater((model) => MineQuickEntry())); | |||
| WidgetFactory.regist('profile_carousel', | |||
| DefaultWidgetCreater((model) => HomeBannerWidget(model))); | |||
| // ==================== 钱包 | |||
| WidgetFactory.regist('wallet_data', DefaultWidgetCreater((model) => WalletData())); | |||
| WidgetFactory.regist('wallet_detail', DefaultWidgetCreater((model) => WalletDetail())); | |||
| WidgetFactory.regist( | |||
| 'wallet_data', DefaultWidgetCreater((model) => WalletData())); | |||
| WidgetFactory.regist( | |||
| 'wallet_detail', DefaultWidgetCreater((model) => WalletDetail())); | |||
| WidgetFactory.regist('wallet_income', DefaultWidgetCreater((model) => WalletIncome())); | |||
| WidgetFactory.regist( | |||
| 'wallet_income', DefaultWidgetCreater((model) => WalletIncome())); | |||
| } | |||
| } | |||
| @@ -1,7 +1,15 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_data/mine_data_sk.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_data/mine_data_widget.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header_bloc.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/model/mine_profile_model.dart'; | |||
| import 'package:zhiying_comm/util/base_bloc.dart'; | |||
| class MineData extends StatefulWidget { | |||
| final Map<String, dynamic> data; | |||
| const MineData(this.data, {Key key}) : super(key: key); | |||
| @override | |||
| _MineDataState createState() => _MineDataState(); | |||
| } | |||
| @@ -9,6 +17,41 @@ class MineData extends StatefulWidget { | |||
| class _MineDataState extends State<MineData> { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return MineDataSkeleton(); | |||
| return BlocProvider<MineHeaderBloc>( | |||
| bloc: MineHeaderBloc(), | |||
| child: _MineDataContainer(widget.data), | |||
| ); | |||
| } | |||
| } | |||
| class _MineDataContainer extends StatefulWidget { | |||
| final Map<String, dynamic> data; | |||
| const _MineDataContainer(this.data, {Key key}) : super(key: key); | |||
| @override | |||
| _MineDataContainerState createState() => _MineDataContainerState(); | |||
| } | |||
| class _MineDataContainerState extends State<_MineDataContainer> { | |||
| MineHeaderBloc _bloc; | |||
| @override | |||
| void initState() { | |||
| _bloc = BlocProvider.of<MineHeaderBloc>(context); | |||
| _bloc.loadData(); | |||
| super.initState(); | |||
| } | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return StreamBuilder<MineProfileModel>( | |||
| stream: _bloc.outData, | |||
| builder: (BuildContext context, AsyncSnapshot snapshot) { | |||
| MineProfileModel profile = snapshot.data; | |||
| return profile == null | |||
| ? MineDataSkeleton() | |||
| : MineDataWidget(profile, widget.data); | |||
| }); | |||
| } | |||
| } | |||
| @@ -1,12 +0,0 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_data/mine_data.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MineDataCreater extends WidgetCreater { | |||
| @override | |||
| List<Widget> createWidgets(Map<String, dynamic> model) { | |||
| return [ | |||
| MineData(), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -0,0 +1,262 @@ | |||
| import 'dart:convert' as convert; | |||
| import 'package:cached_network_image/cached_network_image.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_data/model/mine_data_model.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/model/mine_profile_model.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MineDataWidget extends StatelessWidget { | |||
| final Map<String, dynamic> data; | |||
| final MineProfileModel profile; | |||
| Map<String, dynamic> _json; | |||
| MineDataModel _style; | |||
| MineDataWidget( | |||
| this.profile, | |||
| this.data, { | |||
| Key key, | |||
| }) : super(key: key) { | |||
| String d = data['data']; | |||
| _json = convert.jsonDecode(d); | |||
| _style = MineDataModel.fromJson(Map<String, dynamic>.from(_json)); | |||
| } | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container( | |||
| margin: EdgeInsets.only(left: 12.5, right: 12.5), | |||
| decoration: BoxDecoration( | |||
| color: HexColor.fromHex(_style.gridViewBgColor), | |||
| borderRadius: BorderRadius.circular(7.5)), | |||
| child: Column( | |||
| children: <Widget>[ | |||
| _createTop(context), | |||
| _createCenter(), | |||
| ], | |||
| ), | |||
| ); | |||
| } | |||
| Widget _createTop(BuildContext context) { | |||
| return Container( | |||
| width: double.infinity, | |||
| height: 62, | |||
| child: Stack( | |||
| children: <Widget>[ | |||
| Container( | |||
| width: double.infinity, | |||
| height: double.infinity, | |||
| child: ClipRRect( | |||
| borderRadius: BorderRadius.only( | |||
| topLeft: Radius.circular(7.5), | |||
| topRight: Radius.circular(7.5)), | |||
| child: CachedNetworkImage( | |||
| imageUrl: _style.accumulatedEarningsBgImg, | |||
| fit: BoxFit.cover, | |||
| ), | |||
| ), | |||
| ), | |||
| Container( | |||
| width: double.infinity, | |||
| height: double.infinity, | |||
| child: Row( | |||
| mainAxisAlignment: MainAxisAlignment.center, | |||
| crossAxisAlignment: CrossAxisAlignment.center, | |||
| children: <Widget>[ | |||
| Expanded( | |||
| child: Container( | |||
| margin: EdgeInsets.only(left: 15, right: 15), | |||
| child: Column( | |||
| mainAxisAlignment: MainAxisAlignment.center, | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| children: <Widget>[ | |||
| Text( | |||
| '累计收益', | |||
| style: TextStyle( | |||
| fontSize: 11, | |||
| fontWeight: FontWeight.w600, | |||
| color: HexColor.fromHex( | |||
| _style.accumulatedEarningsNameColor), | |||
| ), | |||
| ), | |||
| Text( | |||
| '${profile.total}', | |||
| style: TextStyle( | |||
| fontSize: 18, | |||
| fontWeight: FontWeight.w800, | |||
| color: HexColor.fromHex( | |||
| _style.accumulatedEarningsNameColor), | |||
| fontFamily: 'Din', | |||
| package: 'zhiying_base_widget', | |||
| ), | |||
| ), | |||
| ], | |||
| ), | |||
| ), | |||
| ), | |||
| GestureDetector( | |||
| child: Container( | |||
| margin: EdgeInsets.only(right: 30), | |||
| width: 64, | |||
| height: 24, | |||
| child: Stack( | |||
| children: <Widget>[ | |||
| CachedNetworkImage( | |||
| imageUrl: _style.btnImg, | |||
| fit: BoxFit.cover, | |||
| ), | |||
| Center( | |||
| child: Text( | |||
| _style.btnText, | |||
| style: TextStyle( | |||
| fontSize: 12, | |||
| color: HexColor.fromHex(_style.btnTextColor)), | |||
| ), | |||
| ) | |||
| ], | |||
| ), | |||
| ), | |||
| onTap: () { | |||
| RouterUtil.route(_json, context); | |||
| }, | |||
| ) | |||
| ], | |||
| ), | |||
| ) | |||
| ], | |||
| ), | |||
| ); | |||
| } | |||
| Widget _createCenter() { | |||
| List<MineProfileDataModel> datas = profile.datas; | |||
| int maxColumn = 2; | |||
| int row = (datas.length / 2).ceil(); | |||
| if (row % 3 == 0) { | |||
| maxColumn = 3; | |||
| } | |||
| List<Widget> rows = List(); | |||
| List<Widget> columns = List(); | |||
| int i = 0; | |||
| for (; i < row; i++) { | |||
| rows.add( | |||
| _createrCenterItem(datas[i].name, datas[i].value), | |||
| ); | |||
| if (i % maxColumn == maxColumn - 1 || i == row - 1) { | |||
| columns.add(Row( | |||
| crossAxisAlignment: CrossAxisAlignment.center, | |||
| mainAxisAlignment: MainAxisAlignment.center, | |||
| children: rows, | |||
| )); | |||
| rows = List(); | |||
| } else { | |||
| rows.add(Container( | |||
| height: 33, | |||
| width: 0.5, | |||
| color: HexColor.fromHex('#ebebeb'), | |||
| )); | |||
| } | |||
| } | |||
| if (i < datas.length) { | |||
| columns.add(Container( | |||
| height: 0.5, | |||
| color: HexColor.fromHex('#ebebeb'), | |||
| )); | |||
| } | |||
| for (; i < datas.length; i++) { | |||
| rows.add( | |||
| _createBottomItem(datas[i].name, datas[i].value), | |||
| ); | |||
| if ((i - row) % maxColumn == maxColumn - 1 || | |||
| i == row - 1 || | |||
| i == datas.length - 1) { | |||
| columns.add(Row( | |||
| crossAxisAlignment: CrossAxisAlignment.center, | |||
| mainAxisAlignment: MainAxisAlignment.center, | |||
| children: rows, | |||
| )); | |||
| rows = List(); | |||
| } else { | |||
| rows.add(Container( | |||
| height: 33, | |||
| width: 0.5, | |||
| color: HexColor.fromHex('#ebebeb'), | |||
| )); | |||
| } | |||
| } | |||
| return Container( | |||
| width: double.infinity, | |||
| child: Column( | |||
| children: columns, | |||
| ), | |||
| ); | |||
| } | |||
| Widget _createrCenterItem(String name, String value) { | |||
| return Expanded( | |||
| child: Container( | |||
| padding: EdgeInsets.only(left: 15, right: 15), | |||
| height: 72, | |||
| child: Column( | |||
| mainAxisAlignment: MainAxisAlignment.center, | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| children: <Widget>[ | |||
| Text( | |||
| name, | |||
| style: TextStyle( | |||
| fontSize: 11, | |||
| color: HexColor.fromHex(_style.gridViewNameColor)), | |||
| ), | |||
| Padding( | |||
| padding: const EdgeInsets.only(top: 2), | |||
| child: Text( | |||
| value, | |||
| style: TextStyle( | |||
| fontSize: 18, | |||
| color: HexColor.fromHex(_style.gridViewValueColor), | |||
| fontFamily: 'Din', | |||
| package: 'zhiying_base_widget'), | |||
| ), | |||
| ), | |||
| ], | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| Widget _createBottomItem(String name, String value) { | |||
| return Expanded( | |||
| child: Container( | |||
| padding: EdgeInsets.only(left: 15, right: 15), | |||
| height: 46, | |||
| child: Row( | |||
| mainAxisAlignment: MainAxisAlignment.start, | |||
| crossAxisAlignment: CrossAxisAlignment.center, | |||
| children: <Widget>[ | |||
| Text( | |||
| name, | |||
| style: TextStyle( | |||
| fontSize: 12, | |||
| color: HexColor.fromHex(_style.gridViewNameColor)), | |||
| ), | |||
| Padding( | |||
| padding: const EdgeInsets.only(left: 2), | |||
| child: Text( | |||
| value, | |||
| style: TextStyle( | |||
| fontSize: 12, | |||
| color: HexColor.fromHex(_style.gridViewValueColor), | |||
| fontFamily: 'Din', | |||
| package: 'zhiying_base_widget'), | |||
| ), | |||
| ), | |||
| ], | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,62 @@ | |||
| import 'package:json_annotation/json_annotation.dart'; | |||
| part 'mine_data_model.g.dart'; | |||
| @JsonSerializable() | |||
| class MineDataModel extends Object { | |||
| @JsonKey(name: 'accumulated_earnings_name_color') | |||
| String accumulatedEarningsNameColor; | |||
| @JsonKey(name: 'accumulated_earnings_color') | |||
| String accumulatedEarningsColor; | |||
| @JsonKey(name: 'accumulated_earnings_bg_img') | |||
| String accumulatedEarningsBgImg; | |||
| @JsonKey(name: 'btn_text') | |||
| String btnText; | |||
| @JsonKey(name: 'btn_text_color') | |||
| String btnTextColor; | |||
| @JsonKey(name: 'btn_img') | |||
| String btnImg; | |||
| @JsonKey(name: 'required_login') | |||
| String requiredLogin; | |||
| @JsonKey(name: 'required_taobao_auth') | |||
| String requiredTaobaoAuth; | |||
| @JsonKey(name: 'skip_identifier') | |||
| String skipIdentifier; | |||
| @JsonKey(name: 'grid_view_bg_color') | |||
| String gridViewBgColor; | |||
| @JsonKey(name: 'grid_view_name_color') | |||
| String gridViewNameColor; | |||
| @JsonKey(name: 'grid_view_value_color') | |||
| String gridViewValueColor; | |||
| MineDataModel( | |||
| this.accumulatedEarningsNameColor, | |||
| this.accumulatedEarningsColor, | |||
| this.accumulatedEarningsBgImg, | |||
| this.btnText, | |||
| this.btnTextColor, | |||
| this.btnImg, | |||
| this.requiredLogin, | |||
| this.requiredTaobaoAuth, | |||
| this.skipIdentifier, | |||
| this.gridViewBgColor, | |||
| this.gridViewNameColor, | |||
| this.gridViewValueColor, | |||
| ); | |||
| factory MineDataModel.fromJson(Map<String, dynamic> srcJson) => | |||
| _$MineDataModelFromJson(srcJson); | |||
| Map<String, dynamic> toJson() => _$MineDataModelToJson(this); | |||
| } | |||
| @@ -0,0 +1,40 @@ | |||
| // GENERATED CODE - DO NOT MODIFY BY HAND | |||
| part of 'mine_data_model.dart'; | |||
| // ************************************************************************** | |||
| // JsonSerializableGenerator | |||
| // ************************************************************************** | |||
| MineDataModel _$MineDataModelFromJson(Map<String, dynamic> json) { | |||
| return MineDataModel( | |||
| json['accumulated_earnings_name_color'] as String, | |||
| json['accumulated_earnings_color'] as String, | |||
| json['accumulated_earnings_bg_img'] as String, | |||
| json['btn_text'] as String, | |||
| json['btn_text_color'] as String, | |||
| json['btn_img'] as String, | |||
| json['required_login'] as String, | |||
| json['required_taobao_auth'] as String, | |||
| json['skip_identifier'] as String, | |||
| json['grid_view_bg_color'] as String, | |||
| json['grid_view_name_color'] as String, | |||
| json['grid_view_value_color'] as String, | |||
| ); | |||
| } | |||
| Map<String, dynamic> _$MineDataModelToJson(MineDataModel instance) => | |||
| <String, dynamic>{ | |||
| 'accumulated_earnings_name_color': instance.accumulatedEarningsNameColor, | |||
| 'accumulated_earnings_color': instance.accumulatedEarningsColor, | |||
| 'accumulated_earnings_bg_img': instance.accumulatedEarningsBgImg, | |||
| 'btn_text': instance.btnText, | |||
| 'btn_text_color': instance.btnTextColor, | |||
| 'btn_img': instance.btnImg, | |||
| 'required_login': instance.requiredLogin, | |||
| 'required_taobao_auth': instance.requiredTaobaoAuth, | |||
| 'skip_identifier': instance.skipIdentifier, | |||
| 'grid_view_bg_color': instance.gridViewBgColor, | |||
| 'grid_view_name_color': instance.gridViewNameColor, | |||
| 'grid_view_value_color': instance.gridViewValueColor, | |||
| }; | |||
| @@ -1,9 +1,11 @@ | |||
| import 'dart:convert' as convert; | |||
| import 'package:cached_network_image/cached_network_image.dart'; | |||
| import 'package:flutter/cupertino.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/model/mine_header_model.dart'; | |||
| import 'package:provider/provider.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header_bloc.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header_container.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header_sk.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header_static_container.dart'; | |||
| import 'package:zhiying_comm/util/base_bloc.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MineHeader extends StatefulWidget { | |||
| @@ -16,76 +18,34 @@ class MineHeader extends StatefulWidget { | |||
| } | |||
| class _MineHeaderState extends State<MineHeader> { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return _MineContainer(widget.data); | |||
| } | |||
| } | |||
| class _MineContainer extends StatefulWidget { | |||
| final Map<String, dynamic> data; | |||
| Map<String, dynamic> json; | |||
| MineHeaderModel staticModel; | |||
| _MineContainer(this.data, {Key key}) : super(key: key) { | |||
| String d = data['data']; | |||
| json = convert.jsonDecode(d); | |||
| staticModel = MineHeaderModel.fromJson(json); | |||
| } | |||
| UserInfoModel _user; | |||
| bool _isSketelon = true; | |||
| @override | |||
| _MineContainerState createState() => _MineContainerState(); | |||
| } | |||
| void initState() { | |||
| super.initState(); | |||
| } | |||
| class _MineContainerState extends State<_MineContainer> { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container( | |||
| child: Row( | |||
| children: <Widget>[ | |||
| GestureDetector( | |||
| child: Container( | |||
| margin: EdgeInsets.only(left: 20, top: 20, bottom: 20, right: 12), | |||
| width: 56, | |||
| height: 56, | |||
| child: ClipRRect( | |||
| borderRadius: BorderRadius.circular(28), | |||
| child: CachedNetworkImage( | |||
| imageUrl: widget.staticModel.defaultAvatar, | |||
| fit: BoxFit.cover)), | |||
| ), | |||
| onTap: () { | |||
| RouterUtil.route(widget.json, context); | |||
| }, | |||
| ), | |||
| Expanded( | |||
| child: Column( | |||
| mainAxisAlignment: MainAxisAlignment.start, | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| children: <Widget>[ | |||
| Container( | |||
| width: 120, | |||
| height: 20, | |||
| child: Text( | |||
| widget.staticModel.loginName, | |||
| style: TextStyle( | |||
| color: HexColor.fromHex(widget.staticModel.loginColor), | |||
| fontSize: 17), | |||
| ), | |||
| ), | |||
| Container( | |||
| margin: EdgeInsets.only(top: 8), | |||
| width: 80, | |||
| child: Text( | |||
| widget.staticModel.loginNameHelpText, | |||
| style: TextStyle( | |||
| color: HexColor.fromHex(widget.staticModel.loginColor), | |||
| fontSize: 13), | |||
| )), | |||
| ], | |||
| )) | |||
| ], | |||
| ), | |||
| if (_isSketelon) { | |||
| Provider.of<UserInfoNotifier>(context).getUserInfoModel().then((user) { | |||
| setState(() { | |||
| _user = user; | |||
| _isSketelon = false; | |||
| }); | |||
| }); | |||
| } | |||
| if (_isSketelon) { | |||
| return MineHeaderSkeleton(); | |||
| } | |||
| if (_user == null) { | |||
| return MineStaticContainer(widget.data); | |||
| } | |||
| return BlocProvider<MineHeaderBloc>( | |||
| bloc: MineHeaderBloc(), | |||
| child: MineHeaderContainer(widget.data), | |||
| ); | |||
| } | |||
| } | |||
| @@ -1,37 +1,28 @@ | |||
| import 'dart:async'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/model/mine_profile_model.dart'; | |||
| import 'package:zhiying_comm/util/base_bloc.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MineHeaderBloc extends BlocBase { | |||
| Map<String, dynamic> _mineData; | |||
| MineProfileModel _profile; | |||
| StreamController<Map<String, dynamic>> _mineController = | |||
| StreamController<Map<String, dynamic>>(); | |||
| StreamController<MineProfileModel> _profileController = | |||
| StreamController<MineProfileModel>(); | |||
| Stream<Map<String, dynamic>> get outData => _mineController.stream; | |||
| Stream<MineProfileModel> get outData => _profileController.stream; | |||
| @override | |||
| void dispose() { | |||
| _mineController.close(); | |||
| _mineController = null; | |||
| _profileController.close(); | |||
| _profileController = null; | |||
| } | |||
| void loadData(int id) { | |||
| void loadData() { | |||
| NetUtil.request('/api/v1/user/profile', | |||
| method: NetMethod.POST, | |||
| params: Map<String, dynamic>.from({ | |||
| 'ids': [id] | |||
| }), | |||
| onCache: (data) {}, onSuccess: (data) { | |||
| _loadData(id, data); | |||
| method: NetMethod.GET, onCache: (data) {}, onSuccess: (data) { | |||
| _profile = MineProfileModel.fromJson(Map<String, dynamic>.from(data)); | |||
| _profileController.add(_profile); | |||
| }); | |||
| } | |||
| void _loadData(int id, dynamic data) { | |||
| String key = id.toString(); | |||
| Map<String, dynamic> json = Map<String, dynamic>.from(data); | |||
| _mineController.add(_mineData); | |||
| } | |||
| } | |||
| @@ -0,0 +1,154 @@ | |||
| import 'dart:convert' as convert; | |||
| import 'package:cached_network_image/cached_network_image.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter/services.dart'; | |||
| import 'package:fluttertoast/fluttertoast.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header_bloc.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header_sk.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/model/mine_header_model.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/model/mine_profile_model.dart'; | |||
| import 'package:zhiying_comm/util/base_bloc.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MineHeaderContainer extends StatefulWidget { | |||
| final Map<String, dynamic> data; | |||
| Map<String, dynamic> json; | |||
| MineHeaderModel staticModel; | |||
| MineHeaderContainer(this.data, {Key key}) : super(key: key) { | |||
| String d = data['data']; | |||
| json = convert.jsonDecode(d); | |||
| staticModel = MineHeaderModel.fromJson(json); | |||
| } | |||
| @override | |||
| _MineHeaderContainerState createState() => _MineHeaderContainerState(); | |||
| } | |||
| class _MineHeaderContainerState extends State<MineHeaderContainer> { | |||
| MineHeaderBloc _bloc; | |||
| @override | |||
| void initState() { | |||
| _bloc = BlocProvider.of<MineHeaderBloc>(context); | |||
| _bloc.loadData(); | |||
| super.initState(); | |||
| } | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return StreamBuilder<MineProfileModel>( | |||
| stream: _bloc.outData, | |||
| builder: (BuildContext context, AsyncSnapshot snapshot) { | |||
| MineProfileModel profile = snapshot.data; | |||
| return profile == null | |||
| ? MineHeaderSkeleton() | |||
| : Row( | |||
| children: <Widget>[ | |||
| GestureDetector( | |||
| child: Container( | |||
| margin: EdgeInsets.only( | |||
| left: 20, top: 20, bottom: 20, right: 12), | |||
| width: 56, | |||
| height: 56, | |||
| child: CachedNetworkImage( | |||
| imageUrl: profile.avatar, | |||
| fit: BoxFit.cover, | |||
| ), | |||
| ), | |||
| onTap: () { | |||
| RouterUtil.route(widget.json, context); | |||
| }, | |||
| ), | |||
| Expanded( | |||
| child: Container( | |||
| margin: EdgeInsets.only(right: 12), | |||
| child: Column( | |||
| mainAxisAlignment: MainAxisAlignment.start, | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| children: <Widget>[ | |||
| Row( | |||
| children: <Widget>[ | |||
| Text( | |||
| profile.username, | |||
| maxLines: 1, | |||
| overflow: TextOverflow.ellipsis, | |||
| style: TextStyle( | |||
| fontSize: 17, | |||
| color: HexColor.fromHex( | |||
| widget.staticModel.userNameColor)), | |||
| ), | |||
| Container( | |||
| height: 18, | |||
| margin: EdgeInsets.only(left: 6), | |||
| padding: EdgeInsets.only(left: 6, right: 6), | |||
| decoration: BoxDecoration( | |||
| color: HexColor.fromHex( | |||
| widget.staticModel.lvBgColor), | |||
| borderRadius: BorderRadius.circular(9)), | |||
| child: Row( | |||
| children: <Widget>[ | |||
| Container( | |||
| width: 12, | |||
| height: 12, | |||
| margin: EdgeInsets.only(right: 2), | |||
| child: CachedNetworkImage( | |||
| imageUrl: profile.userLvIcon, | |||
| fit: BoxFit.contain, | |||
| ), | |||
| ), | |||
| Text( | |||
| profile.userLvName, | |||
| style: TextStyle( | |||
| fontSize: 10, | |||
| color: HexColor.fromHex( | |||
| widget.staticModel.lvNameColor)), | |||
| ) | |||
| ], | |||
| ), | |||
| ), | |||
| ], | |||
| ), | |||
| GestureDetector( | |||
| child: Container( | |||
| margin: EdgeInsets.only(top: 8), | |||
| child: Row( | |||
| children: <Widget>[ | |||
| Text( | |||
| '邀请码:${profile.inviteCode}', | |||
| maxLines: 1, | |||
| style: TextStyle( | |||
| fontSize: 13, | |||
| color: HexColor.fromHex( | |||
| widget.staticModel.userNameColor), | |||
| fontFamily: 'Din', | |||
| package: 'zhiying_base_widget', | |||
| ), | |||
| ), | |||
| Container( | |||
| width: 12, | |||
| height: 12, | |||
| margin: EdgeInsets.only(left: 2), | |||
| child: CachedNetworkImage( | |||
| imageUrl: widget.staticModel.coypeIcon, | |||
| fit: BoxFit.contain, | |||
| ), | |||
| ), | |||
| ], | |||
| ), | |||
| ), | |||
| onTap: () { | |||
| Fluttertoast.showToast(msg: '复制成功'); | |||
| Clipboard.setData( | |||
| ClipboardData(text: profile.inviteCode)); | |||
| }, | |||
| ), | |||
| ], | |||
| ), | |||
| )) | |||
| ], | |||
| ); | |||
| }); | |||
| } | |||
| } | |||
| @@ -0,0 +1,77 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine/mine_header/model/mine_header_model.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| import 'package:cached_network_image/cached_network_image.dart'; | |||
| import 'dart:convert' as convert; | |||
| // 未登录状态个人中心头部 | |||
| class MineStaticContainer extends StatefulWidget { | |||
| final Map<String, dynamic> data; | |||
| Map<String, dynamic> json; | |||
| MineHeaderModel staticModel; | |||
| MineStaticContainer(this.data, {Key key}) : super(key: key) { | |||
| String d = data['data']; | |||
| json = convert.jsonDecode(d); | |||
| staticModel = MineHeaderModel.fromJson(json); | |||
| } | |||
| @override | |||
| _MineStaticContainerState createState() => _MineStaticContainerState(); | |||
| } | |||
| class _MineStaticContainerState extends State<MineStaticContainer> { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container( | |||
| child: Row( | |||
| children: <Widget>[ | |||
| GestureDetector( | |||
| child: Container( | |||
| margin: EdgeInsets.only(left: 20, top: 20, bottom: 20, right: 12), | |||
| width: 56, | |||
| height: 56, | |||
| child: ClipRRect( | |||
| borderRadius: BorderRadius.circular(28), | |||
| child: CachedNetworkImage( | |||
| imageUrl: widget.staticModel.defaultAvatar, | |||
| fit: BoxFit.cover)), | |||
| ), | |||
| onTap: () { | |||
| RouterUtil.route(widget.json, context); | |||
| }, | |||
| ), | |||
| Expanded( | |||
| child: Column( | |||
| mainAxisAlignment: MainAxisAlignment.start, | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| children: <Widget>[ | |||
| Container( | |||
| width: 120, | |||
| height: 20, | |||
| child: Text( | |||
| widget.staticModel.loginName, | |||
| style: TextStyle( | |||
| color: HexColor.fromHex( | |||
| widget.staticModel.loginColor), | |||
| fontSize: 17), | |||
| ), | |||
| ), | |||
| Container( | |||
| margin: EdgeInsets.only(top: 8), | |||
| width: 80, | |||
| child: Text( | |||
| widget.staticModel.loginNameHelpText, | |||
| style: TextStyle( | |||
| color: HexColor.fromHex( | |||
| widget.staticModel.loginColor), | |||
| fontSize: 13), | |||
| )), | |||
| ], | |||
| )) | |||
| ], | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| @@ -4,6 +4,12 @@ part 'mine_header_model.g.dart'; | |||
| @JsonSerializable() | |||
| class MineHeaderModel extends Object { | |||
| @JsonKey(name: 'lv_bg_color') | |||
| String lvBgColor; | |||
| @JsonKey(name: 'lv_name_color') | |||
| String lvNameColor; | |||
| @JsonKey(name: 'non_login_avatar') | |||
| String defaultAvatar; | |||
| @@ -19,11 +19,15 @@ MineHeaderModel _$MineHeaderModelFromJson(Map<String, dynamic> json) { | |||
| json['required_login'] as String, | |||
| json['required_taobao_auth'] as String, | |||
| json['skip_identifier'] as String, | |||
| ); | |||
| ) | |||
| ..lvBgColor = json['lv_bg_color'] as String | |||
| ..lvNameColor = json['lv_name_color'] as String; | |||
| } | |||
| Map<String, dynamic> _$MineHeaderModelToJson(MineHeaderModel instance) => | |||
| <String, dynamic>{ | |||
| 'lv_bg_color': instance.lvBgColor, | |||
| 'lv_name_color': instance.lvNameColor, | |||
| 'non_login_avatar': instance.defaultAvatar, | |||
| 'user_name_color': instance.userNameColor, | |||
| 'invited_code_text': instance.invitedCodeText, | |||
| @@ -0,0 +1,57 @@ | |||
| import 'package:json_annotation/json_annotation.dart'; | |||
| part 'mine_profile_model.g.dart'; | |||
| @JsonSerializable() | |||
| class MineProfileModel extends Object { | |||
| @JsonKey(name: 'username') | |||
| String username; | |||
| @JsonKey(name: 'avatar') | |||
| String avatar; | |||
| @JsonKey(name: 'InviteCode') | |||
| String inviteCode; | |||
| @JsonKey(name: 'user_lv_name') | |||
| String userLvName; | |||
| @JsonKey(name: 'user_lv_icon') | |||
| String userLvIcon; | |||
| @JsonKey(name: 'total') | |||
| String total; | |||
| @JsonKey(name: 'grid_views') | |||
| List<MineProfileDataModel> datas; | |||
| MineProfileModel(this.username, | |||
| this.avatar, | |||
| this.inviteCode, | |||
| this.userLvName, | |||
| this.userLvIcon, | |||
| this.total, | |||
| this.datas,); | |||
| factory MineProfileModel.fromJson(Map<String, dynamic> srcJson) => | |||
| _$MineProfileModelFromJson(srcJson); | |||
| Map<String, dynamic> toJson() => _$MineProfileModelToJson(this); | |||
| } | |||
| @JsonSerializable() | |||
| class MineProfileDataModel extends Object { | |||
| @JsonKey(name: 'name') | |||
| String name; | |||
| @JsonKey(name: 'value') | |||
| String value; | |||
| MineProfileDataModel(this.name, | |||
| this.value,); | |||
| factory MineProfileDataModel.fromJson(Map<String, dynamic> srcJson) => | |||
| _$MineProfileDataModelFromJson(srcJson); | |||
| Map<String, dynamic> toJson() => _$MineProfileDataModelToJson(this); | |||
| } | |||
| @@ -0,0 +1,48 @@ | |||
| // GENERATED CODE - DO NOT MODIFY BY HAND | |||
| part of 'mine_profile_model.dart'; | |||
| // ************************************************************************** | |||
| // JsonSerializableGenerator | |||
| // ************************************************************************** | |||
| MineProfileModel _$MineProfileModelFromJson(Map<String, dynamic> json) { | |||
| return MineProfileModel( | |||
| json['username'] as String, | |||
| json['avatar'] as String, | |||
| json['InviteCode'] as String, | |||
| json['user_lv_name'] as String, | |||
| json['user_lv_icon'] as String, | |||
| json['total'] as String, | |||
| (json['grid_views'] as List) | |||
| ?.map((e) => e == null | |||
| ? null | |||
| : MineProfileDataModel.fromJson(e as Map<String, dynamic>)) | |||
| ?.toList(), | |||
| ); | |||
| } | |||
| Map<String, dynamic> _$MineProfileModelToJson(MineProfileModel instance) => | |||
| <String, dynamic>{ | |||
| 'username': instance.username, | |||
| 'avatar': instance.avatar, | |||
| 'InviteCode': instance.inviteCode, | |||
| 'user_lv_name': instance.userLvName, | |||
| 'user_lv_icon': instance.userLvIcon, | |||
| 'total': instance.total, | |||
| 'grid_views': instance.datas, | |||
| }; | |||
| MineProfileDataModel _$MineProfileDataModelFromJson(Map<String, dynamic> json) { | |||
| return MineProfileDataModel( | |||
| json['name'] as String, | |||
| json['value'] as String, | |||
| ); | |||
| } | |||
| Map<String, dynamic> _$MineProfileDataModelToJson( | |||
| MineProfileDataModel instance) => | |||
| <String, dynamic>{ | |||
| 'name': instance.name, | |||
| 'value': instance.value, | |||
| }; | |||
| @@ -26,19 +26,7 @@ class MineNavDelegate extends SliverPersistentHeaderDelegate { | |||
| List icons = json['app_bar_icons']; | |||
| _icons = icons.map((icon) { | |||
| SkipModel model = SkipModel.fromJson(Map<String, dynamic>.from(icon)); | |||
| return GestureDetector( | |||
| child: Container( | |||
| width: 24, | |||
| height: 24, | |||
| margin: EdgeInsets.only(left: 6), | |||
| child: CachedNetworkImage( | |||
| imageUrl: model.icon, | |||
| ), | |||
| ), | |||
| onTap: () { | |||
| print('页面跳转 ${model.skipIdentifier}'); | |||
| }, | |||
| ); | |||
| return MineNavIcon(model, json); | |||
| }).toList(); | |||
| } | |||
| } | |||
| @@ -88,3 +76,28 @@ class MineNav extends StatelessWidget { | |||
| )); | |||
| } | |||
| } | |||
| class MineNavIcon extends StatelessWidget { | |||
| final SkipModel model; | |||
| final Map<String, dynamic> data; | |||
| const MineNavIcon(this.model, this.data, {Key key}) : super(key: key); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return GestureDetector( | |||
| child: Container( | |||
| width: 24, | |||
| height: 24, | |||
| margin: EdgeInsets.only(left: 6), | |||
| child: CachedNetworkImage( | |||
| imageUrl: model.icon, | |||
| ), | |||
| ), | |||
| onTap: () { | |||
| print('页面跳转 ${model.skipIdentifier}'); | |||
| RouterUtil.route(data, context); | |||
| }, | |||
| ); | |||
| } | |||
| } | |||