From f0c8142df424d297073771cc7f383db4e4b4a00b Mon Sep 17 00:00:00 2001 From: PH2 <1293456824@qq.com> Date: Thu, 29 Oct 2020 14:07:25 +0800 Subject: [PATCH 1/6] =?UTF-8?q?1=E3=80=81=E6=88=91=E7=9A=84=E6=94=B6?= =?UTF-8?q?=E8=97=8F=E5=AE=9E=E7=8E=B0=202=E3=80=81=E5=95=86=E5=93=81?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E5=AE=9E=E7=8E=B0=E6=94=B6=E8=97=8F=E4=B8=8E?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=94=B6=E8=97=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/favorite_page/favorite_page.dart | 22 -- lib/pages/favorite_page/preview_page.dart | 17 - .../favorites_page/bloc/favorites_bloc.dart | 49 +++ .../favorites_page/bloc/favorites_event.dart | 7 + .../bloc/favorites_repository.dart | 39 +++ .../favorites_page/bloc/favorites_state.dart | 23 ++ lib/pages/favorites_page/favorites_page.dart | 264 ++++++++++++++ .../model/favorites_style_model.dart | 278 +++++++++++++++ .../notifier/favorites_page_notifier.dart | 44 +++ lib/register.dart | 8 +- .../dialog/favorites_dialog_widget.dart | 75 ++++ .../bloc/favorites_goods_list_bloc.dart | 173 ++++++++++ .../bloc/favorites_goods_list_event.dart | 39 +++ .../bloc/favorites_goods_list_repository.dart | 161 +++++++++ .../bloc/favorites_goods_list_state.dart | 35 ++ .../favorites_goods_list_widget.dart | 325 ++++++++++++++++++ .../model/favorites_goods_list_model.dart | 37 ++ .../bloc/goods_details_footer_bloc.dart | 25 +- .../bloc/goods_details_footer_event.dart | 15 + .../bloc/goods_details_footer_repository.dart | 40 ++- .../bloc/goods_details_footer_state.dart | 14 +- .../footer/goods_details_footer_widget.dart | 13 +- .../model/goods_details_footer_model.dart | 172 ++++++++- .../home_goods/home_goods_item_single.dart | 8 +- .../home_goods/models/home_goods_model.dart | 15 + 25 files changed, 1820 insertions(+), 78 deletions(-) delete mode 100644 lib/pages/favorite_page/favorite_page.dart delete mode 100644 lib/pages/favorite_page/preview_page.dart create mode 100644 lib/pages/favorites_page/bloc/favorites_bloc.dart create mode 100644 lib/pages/favorites_page/bloc/favorites_event.dart create mode 100644 lib/pages/favorites_page/bloc/favorites_repository.dart create mode 100644 lib/pages/favorites_page/bloc/favorites_state.dart create mode 100644 lib/pages/favorites_page/favorites_page.dart create mode 100644 lib/pages/favorites_page/model/favorites_style_model.dart create mode 100644 lib/pages/favorites_page/notifier/favorites_page_notifier.dart create mode 100644 lib/widgets/favorites/dialog/favorites_dialog_widget.dart create mode 100644 lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart create mode 100644 lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart create mode 100644 lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart create mode 100644 lib/widgets/favorites/goods_list/bloc/favorites_goods_list_state.dart create mode 100644 lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart create mode 100644 lib/widgets/favorites/goods_list/model/favorites_goods_list_model.dart diff --git a/lib/pages/favorite_page/favorite_page.dart b/lib/pages/favorite_page/favorite_page.dart deleted file mode 100644 index e61aa72..0000000 --- a/lib/pages/favorite_page/favorite_page.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; - -class FavoritePage extends StatefulWidget { - @override - _FavoritePageState createState() => _FavoritePageState(); -} - -class _FavoritePageState extends State { - GlobalKey _globalKey = GlobalKey(); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text('收藏夹'), - ), - body: Column( - children: [], - ), - ); - } -} diff --git a/lib/pages/favorite_page/preview_page.dart b/lib/pages/favorite_page/preview_page.dart deleted file mode 100644 index 026967e..0000000 --- a/lib/pages/favorite_page/preview_page.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; - -class PreviewPage extends StatelessWidget { - final Image image; - - const PreviewPage({Key key, this.image}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(), - body: Center( - child: image, - ), - ); - } -} diff --git a/lib/pages/favorites_page/bloc/favorites_bloc.dart b/lib/pages/favorites_page/bloc/favorites_bloc.dart new file mode 100644 index 0000000..dcae1c0 --- /dev/null +++ b/lib/pages/favorites_page/bloc/favorites_bloc.dart @@ -0,0 +1,49 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:meta/meta.dart'; +import 'package:zhiying_base_widget/pages/favorites_page/bloc/favorites_repository.dart'; +import 'package:zhiying_base_widget/pages/favorites_page/model/favorites_style_model.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +part 'favorites_event.dart'; + +part 'favorites_state.dart'; + +class FavoritesBloc extends Bloc { + // FavoritesBloc() : super(FavoritesInitial()); + + FavoritesRepository repository; + + FavoritesBloc(this.repository); + + @override + // TODO: implement initialState + FavoritesState get initialState => FavoritesInitial(); + + @override + Stream mapEventToState( + FavoritesEvent event, + ) async* { + /// 初始化 + if (event is FavoritesInitEvent) { + yield* _mapInitEventToState(event); + } + } + + /// 初始化 + Stream _mapInitEventToState(FavoritesInitEvent event) async* { + var cache = await repository.fetchCachedStyle(); + if (!EmptyUtil.isEmpty(cache)) { + yield FavoritesLoadedState(model: cache); + } + var result = await repository.fetchNetStyle(); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesLoadedState(model: result); + } else { + yield FavoritesErrorState(); + } + } +} diff --git a/lib/pages/favorites_page/bloc/favorites_event.dart b/lib/pages/favorites_page/bloc/favorites_event.dart new file mode 100644 index 0000000..bd2f842 --- /dev/null +++ b/lib/pages/favorites_page/bloc/favorites_event.dart @@ -0,0 +1,7 @@ +part of 'favorites_bloc.dart'; + +@immutable +abstract class FavoritesEvent {} + +/// 初始化数据 +class FavoritesInitEvent extends FavoritesEvent {} diff --git a/lib/pages/favorites_page/bloc/favorites_repository.dart b/lib/pages/favorites_page/bloc/favorites_repository.dart new file mode 100644 index 0000000..e11d47c --- /dev/null +++ b/lib/pages/favorites_page/bloc/favorites_repository.dart @@ -0,0 +1,39 @@ +import 'dart:convert'; + +import 'package:zhiying_base_widget/pages/favorites_page/model/favorites_style_model.dart'; +import 'package:zhiying_base_widget/widgets/empty/empty_widget.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class FavoritesRepository { + /// 请求网络样式 + Future fetchNetStyle() async { + try { + var result = await NetUtil.post('/api/v1/mod/pub.flutter.my_fav', cache: true, method: NetMethod.GET); + if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { + var modListData = result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['mod_list'][0]['data']; + if(!EmptyUtil.isEmpty(modListData)){ + return FavoritesStyleModel.fromJson(jsonDecode(modListData)); + } + } + } catch (e, s) { + Logger.log(e, s); + } + return null; + } + + /// 获取缓存样式 + Future fetchCachedStyle() async { + try { + var result = await NetUtil.getRequestCachedData(''); + if(!EmptyUtil.isEmpty(result)){ + var modListData = result['mod_list'][0]['data']; + if(!EmptyUtil.isEmpty(modListData)){ + return FavoritesStyleModel.fromJson(jsonDecode(modListData)); + } + } + } catch (e, s) { + Logger.log(e, s); + } + return null; + } +} diff --git a/lib/pages/favorites_page/bloc/favorites_state.dart b/lib/pages/favorites_page/bloc/favorites_state.dart new file mode 100644 index 0000000..5fc4505 --- /dev/null +++ b/lib/pages/favorites_page/bloc/favorites_state.dart @@ -0,0 +1,23 @@ +part of 'favorites_bloc.dart'; + +@immutable +abstract class FavoritesState extends Equatable { + @override + List get props => []; +} + +/// 初始化状态(骨架图) +class FavoritesInitial extends FavoritesState {} + +/// 数据加载成功 +class FavoritesLoadedState extends FavoritesState { + FavoritesStyleModel model; + + FavoritesLoadedState({@required this.model}); + + @override + List get props => [this.model]; +} + +/// 未知错误 +class FavoritesErrorState extends FavoritesState {} diff --git a/lib/pages/favorites_page/favorites_page.dart b/lib/pages/favorites_page/favorites_page.dart new file mode 100644 index 0000000..19ff195 --- /dev/null +++ b/lib/pages/favorites_page/favorites_page.dart @@ -0,0 +1,264 @@ +import 'package:flutter/material.dart'; +import 'package:tab_indicator_styler/tab_indicator_styler.dart'; +import 'package:zhiying_base_widget/pages/favorites_page/bloc/favorites_bloc.dart'; +import 'package:zhiying_base_widget/pages/favorites_page/bloc/favorites_repository.dart'; +import 'package:zhiying_base_widget/widgets/favorites/goods_list/favorites_goods_list_widget.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; +import 'package:zhiying_comm/util/extension/color.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:provider/provider.dart'; +import 'package:zhiying_comm/util/log/let_log.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:zhiying_comm/util/router_util.dart'; + +import 'model/favorites_style_model.dart'; +import 'notifier/favorites_page_notifier.dart'; + +class FavoritesPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MultiProvider( + providers: [ + ChangeNotifierProvider.value(value: FavoritesPageNotifier()), + ], + child: BlocProvider( + create: (_) => FavoritesBloc(FavoritesRepository())..add(FavoritesInitEvent()), + child: _FavoritesPageContainer(), + ), + ); + } +} + +class _FavoritesPageContainer extends StatefulWidget { + @override + _FavoritesPageContainerState createState() => _FavoritesPageContainerState(); +} + +class _FavoritesPageContainerState extends State<_FavoritesPageContainer> with TickerProviderStateMixin { + TextEditingController _editingController; + FocusNode _focusNode; + TabController _tabController; + bool _isNotEditing = true; + + /// 点击编辑 + void _onClickEditing() { + RouterUtil.hideKeyboard(context); + setState(() { + _isNotEditing = !_isNotEditing; + }); + Provider.of(context, listen: false).editing(); + } + + /// 点击搜索 + void _onClickSearch() {} + + /// 执行搜索 + void _submitSearch() { + String keyword = _editingController?.text?.toString()?.trim(); + // if (!EmptyUtil.isEmpty(keyword)) { + _tabController.index = 0; + Provider.of(context, listen: false).search(keyword); + // } else { + // Fluttertoast.showToast(msg: '请输入需要搜索的内容~'); + // } + } + + /// tabBar的初始化 + void _tabControllerInit(FavoritesStyleModel model) { + if ((null == _tabController && !EmptyUtil.isEmpty(model?.tabList)) || + (!EmptyUtil.isEmpty(model?.tabList) && null != _tabController && _tabController.length != model.tabList.length)) { + _tabController = TabController(length: model.tabList.length, vsync: this) + ..addListener(() { + if (!_tabController.indexIsChanging) { + RouterUtil.hideKeyboard(context); + Logger.log('tab index = ${_tabController.index}'); + Provider.of(context, listen: false).changeSelectIndex(_tabController.index); + } + }); + } + } + + @override + void initState() { + _editingController = TextEditingController(); + _focusNode = FocusNode(); + super.initState(); + } + + @override + void dispose() { + _focusNode?.unfocus(); + _focusNode?.dispose(); + _editingController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return BlocConsumer( + listener: (context, state) {}, + buildWhen: (prev, current) { + return true; + }, + builder: (context, state) { + if (state is FavoritesLoadedState) { + _tabControllerInit(state?.model); + return _buildMainWidget(state?.model); + } + return _buildSkeletonWidget(); + }, + ); + } + + /// mainWidget + Widget _buildMainWidget(FavoritesStyleModel model) { + return Scaffold( + resizeToAvoidBottomInset: false, + resizeToAvoidBottomPadding: false, + backgroundColor: HexColor.fromHex('#FFFFFF'), + appBar: _buildAppBarWidget(model), + body: Column( + children: [ + /// 搜索框 + Padding(padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 4), child: _buildSearchWidget(model)), + + /// tabBar + Padding(padding: const EdgeInsets.only(top: 4), child: _buildTabBarWidget(model)), + + Expanded( + child: _buildTabBarViewWidget(model), + ), + ], + ), + ); + } + + /// TabBar + Widget _buildTabBarWidget(FavoritesStyleModel model) { + return Container( + padding: const EdgeInsets.only(top: 12.5, bottom: 14.5), + width: double.infinity, + child: TabBar( + isScrollable: true, + labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), + unselectedLabelStyle: TextStyle(fontWeight: FontWeight.w400, fontSize: 14), + labelColor: HexColor.fromHex(model?.tabNameSelectedColor ?? '#FF0100'), + unselectedLabelColor: HexColor.fromHex(model?.tabNameColor ?? '#333333'), + indicatorSize: TabBarIndicatorSize.label, + controller: _tabController, + indicatorWeight: 5, + indicator: MaterialIndicator( + topLeftRadius: 1, + topRightRadius: 1, + bottomLeftRadius: 1, + bottomRightRadius: 1, + height: 2, + color: HexColor.fromHex(model?.tabLineColor ?? '#FF0100'), + horizontalPadding: 5, + ), + tabs: model.tabList.map((e) => Text(e?.name ?? '')).toList(), + ), + ); + } + + /// tabBarView + Widget _buildTabBarViewWidget(FavoritesStyleModel model) { + int length = model?.tabList?.length ?? 0; + if (length > 0) { + int index = -1; + return TabBarView( + controller: _tabController, + children: model.tabList.map((e) { + ++index; + return FavoritesGoodsListWidget( + model: model, + type: e?.type, + currentIndex: index, + ); + }).toList(), + ); + } + return Container(color: HexColor.fromHex('#F9F9F9')); + } + + /// 搜索框 + Widget _buildSearchWidget(FavoritesStyleModel model) { + return Container( + alignment: Alignment.center, + width: double.infinity, + height: 35, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(35 / 2), + color: HexColor.fromHex(model?.searchBarBgColor ?? '#F9F9F9'), + ), + child: TextField( + controller: _editingController, + focusNode: _focusNode, + onSubmitted: (text) => _submitSearch(), + textInputAction: TextInputAction.search, + style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 14, textBaseline: TextBaseline.alphabetic), + textAlign: TextAlign.center, + decoration: InputDecoration( + fillColor: Colors.transparent, + filled: true, + isDense: true, + contentPadding: EdgeInsets.zero, + hintText: model?.searchBarText ?? '搜索商品', + hintStyle: TextStyle(color: HexColor.fromHex(model?.searchBarTextColor ?? '#999999'), fontSize: 14, textBaseline: TextBaseline.alphabetic), + border: InputBorder.none, + enabledBorder: InputBorder.none, + disabledBorder: InputBorder.none, + errorBorder: InputBorder.none, + focusedErrorBorder: InputBorder.none, + focusedBorder: InputBorder.none, + ), + ), + ); + } + + /// appbar + Widget _buildAppBarWidget(FavoritesStyleModel model) { + return AppBar( + backgroundColor: HexColor.fromHex(model?.appBarBgColor ?? '#FFFFFF'), + leading: IconButton( + icon: Icon( + Icons.arrow_back_ios, + size: 22, + color: HexColor.fromHex('#333333'), + ), + onPressed: () => Navigator.maybePop(context), + ), + title: Text( + model?.appBarName ?? '我的收藏', + style: TextStyle(color: HexColor.fromHex(model?.appBarNameColor ?? '#333333'), fontSize: 15, fontWeight: FontWeight.bold), + ), + centerTitle: true, + elevation: 0, + actions: [ + GestureDetector( + onTap: () => _onClickEditing(), + behavior: HitTestBehavior.opaque, + child: Center( + child: Padding( + padding: const EdgeInsets.only(right: 12.5), + child: Text( + _isNotEditing ? model?.appBarRightText ?? '编辑' : model?.appBarRightEditingText ?? '完成', + style: TextStyle( + color: HexColor.fromHex(_isNotEditing ? model?.appBarRightTextColor ?? '#333333' : model?.appBarRightEditingColor ?? '#FF4242'), + fontSize: 14, + fontWeight: FontWeight.bold), + ), + ), + ), + ) + ], + ); + } + + /// 骨架图 + Widget _buildSkeletonWidget() { + return Scaffold( + body: Container(), + ); + } +} diff --git a/lib/pages/favorites_page/model/favorites_style_model.dart b/lib/pages/favorites_page/model/favorites_style_model.dart new file mode 100644 index 0000000..e1c9116 --- /dev/null +++ b/lib/pages/favorites_page/model/favorites_style_model.dart @@ -0,0 +1,278 @@ +import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_list_style_model.dart'; + +class FavoritesStyleModel { + String appBarName; + String appBarNameColor; + String appBarBgImg; + String appBarBgColor; + String appBarRightText; + String appBarRightTextColor; + String appBarRightEditingText; + String appBarRightEditingColor; + String searchBarIcon; + String searchBarText; + String searchBarTextColor; + String searchBarBgColor; + String tabLineColor; + String tabItemNotFoundImg; + List tabList; + HomeGoodsListStyleModel listStyle; + String editLeftConfirmColor; + String editLeftNoConfirmColor; + Bottom bottom; + ConfirmDialog confirmDialog; + + String tabNameColor; + String tabNameSelectedColor; + String editLeftConfirmIcon; + String editLeftNoConfirmIcon; + + FavoritesStyleModel({ + this.appBarName, + this.appBarNameColor, + this.appBarBgImg, + this.appBarBgColor, + this.appBarRightText, + this.appBarRightTextColor, + this.appBarRightEditingText, + this.appBarRightEditingColor, + this.searchBarIcon, + this.searchBarText, + this.searchBarTextColor, + this.searchBarBgColor, + this.tabLineColor, + this.tabItemNotFoundImg, + this.tabList, + this.listStyle, + this.editLeftConfirmColor, + this.editLeftNoConfirmColor, + this.bottom, + this.confirmDialog, + this.tabNameColor, + this.tabNameSelectedColor, + this.editLeftConfirmIcon, + this.editLeftNoConfirmIcon, + }); + + FavoritesStyleModel.fromJson(Map json) { + appBarName = json['app_bar_name']; + appBarNameColor = json['app_bar_name_color']; + appBarBgImg = json['app_bar_bg_img']; + appBarBgColor = json['app_bar_bg_color']; + appBarRightText = json['app_bar_right_text']; + appBarRightTextColor = json['app_bar_right_text_color']; + appBarRightEditingText = json['app_bar_right_editing_text']; + appBarRightEditingColor = json['app_bar_right_editing_color']; + searchBarIcon = json['search_bar_icon']; + searchBarText = json['search_bar_text']; + searchBarTextColor = json['search_bar_text_color']; + searchBarBgColor = json['search_bar_bg_color']; + tabLineColor = json['tab_line_color']; + tabItemNotFoundImg = json['tab_item_not_found_img']; + if (json['tab_list'] != null) { + tabList = new List(); + json['tab_list'].forEach((v) { + tabList.add(new TabList.fromJson(v)); + }); + } + listStyle = json['list_style'] != null ? new HomeGoodsListStyleModel.fromJson(json['list_style']) : null; + editLeftConfirmColor = json['edit_left_confirm_color']; + editLeftNoConfirmColor = json['edit_left_no_confirm_color']; + bottom = json['bottom'] != null ? new Bottom.fromJson(json['bottom']) : null; + confirmDialog = json['confirm_dialog'] != null ? new ConfirmDialog.fromJson(json['confirm_dialog']) : null; + + tabNameColor = json['tab_name_color']; + tabNameSelectedColor = json['tab_name_selected_color']; + editLeftConfirmIcon = json['edit_left_confirm_icon']; + editLeftNoConfirmIcon = json['edit_left_no_confirm_icon']; + + } + + Map toJson() { + final Map data = new Map(); + 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_text'] = this.appBarRightText; + data['app_bar_right_text_color'] = this.appBarRightTextColor; + data['app_bar_right_editing_text'] = this.appBarRightEditingText; + data['app_bar_right_editing_color'] = this.appBarRightEditingColor; + data['search_bar_icon'] = this.searchBarIcon; + data['search_bar_text'] = this.searchBarText; + data['search_bar_text_color'] = this.searchBarTextColor; + data['search_bar_bg_color'] = this.searchBarBgColor; + data['tab_line_color'] = this.tabLineColor; + data['tab_item_not_found_img'] = this.tabItemNotFoundImg; + if (this.tabList != null) { + data['tab_list'] = this.tabList.map((v) => v.toJson()).toList(); + } + if (this.listStyle != null) { + data['list_style'] = this.listStyle.toJson(); + } + data['edit_left_confirm_color'] = this.editLeftConfirmColor; + data['edit_left_no_confirm_color'] = this.editLeftNoConfirmColor; + if (this.bottom != null) { + data['bottom'] = this.bottom.toJson(); + } + if (this.confirmDialog != null) { + data['confirm_dialog'] = this.confirmDialog.toJson(); + } + + data['tab_name_color'] = this.tabNameColor; + data['tab_name_selected_color'] = this.tabNameSelectedColor; + data['edit_left_confirm_icon'] = this.editLeftConfirmIcon; + data['edit_left_no_confirm_icon'] = this.editLeftNoConfirmIcon; + + return data; + } +} + +class TabList { + String type; + String name; + String nameColor; + String nameSelectedColor; + + TabList({this.type, this.name, this.nameColor, this.nameSelectedColor}); + + TabList.fromJson(Map json) { + type = json['type']; + name = json['name']; + nameColor = json['name_color']; + nameSelectedColor = json['name_selected_color']; + } + + Map toJson() { + final Map data = new Map(); + data['type'] = this.type; + data['name'] = this.name; + data['name_color'] = this.nameColor; + data['name_selected_color'] = this.nameSelectedColor; + return data; + } +} + +class Left { + String couonText; + String couponFontColor; + String couponBgColor; + String couponBgImg; + String isImg; + + Left({this.couonText, this.couponFontColor, this.couponBgColor, this.couponBgImg, this.isImg}); + + Left.fromJson(Map json) { + couonText = json['couon_text']; + couponFontColor = json['coupon_font_color']; + couponBgColor = json['coupon_bg_color']; + couponBgImg = json['coupon_bg_img']; + isImg = json['is_img']; + } + + Map toJson() { + final Map data = new Map(); + data['couon_text'] = this.couonText; + data['coupon_font_color'] = this.couponFontColor; + data['coupon_bg_color'] = this.couponBgColor; + data['coupon_bg_img'] = this.couponBgImg; + data['is_img'] = this.isImg; + return data; + } +} + +class Right { + String commissionText; + String commissionFontColor; + String commissionBgColor; + String commissionBgImg; + String isImg; + + Right({this.commissionText, this.commissionFontColor, this.commissionBgColor, this.commissionBgImg, this.isImg}); + + Right.fromJson(Map json) { + commissionText = json['commission_text']; + commissionFontColor = json['commission_font_color']; + commissionBgColor = json['commission_bg_color']; + commissionBgImg = json['commission_bg_img']; + isImg = json['is_img']; + } + + Map toJson() { + final Map data = new Map(); + data['commission_text'] = this.commissionText; + data['commission_font_color'] = this.commissionFontColor; + data['commission_bg_color'] = this.commissionBgColor; + data['commission_bg_img'] = this.commissionBgImg; + data['is_img'] = this.isImg; + return data; + } +} + +class Bottom { + String bgColor; + String leftText; + String leftColor; + String rightText; + String rightColor; + + Bottom({this.bgColor, this.leftText, this.leftColor, this.rightText, this.rightColor}); + + Bottom.fromJson(Map json) { + bgColor = json['bg_color']; + leftText = json['left_text']; + leftColor = json['left_color']; + rightText = json['right_text']; + rightColor = json['right_color']; + } + + Map toJson() { + final Map data = new Map(); + data['bg_color'] = this.bgColor; + data['left_text'] = this.leftText; + data['left_color'] = this.leftColor; + data['right_text'] = this.rightText; + data['right_color'] = this.rightColor; + return data; + } +} + +class ConfirmDialog { + String bgText; + String bgTextColor; + String bgColor; + String leftText; + String leftTextColor; + String leftBtnBgColor; + String rightText; + String rightTextColor; + String rightBtnBgColor; + + ConfirmDialog({this.bgText, this.bgTextColor, this.bgColor, this.leftText, this.leftTextColor, this.leftBtnBgColor, this.rightText, this.rightTextColor, this.rightBtnBgColor}); + + ConfirmDialog.fromJson(Map json) { + bgText = json['bg_text']; + bgTextColor = json['bg_text_color']; + bgColor = json['bg_color']; + leftText = json['left_text']; + leftTextColor = json['left_text_color']; + leftBtnBgColor = json['left_btn_bg_color']; + rightText = json['right_text']; + rightTextColor = json['right_text_color']; + rightBtnBgColor = json['right_btn_bg_color']; + } + + Map toJson() { + final Map data = new Map(); + data['bg_text'] = this.bgText; + data['bg_text_color'] = this.bgTextColor; + data['bg_color'] = this.bgColor; + data['left_text'] = this.leftText; + data['left_text_color'] = this.leftTextColor; + data['left_btn_bg_color'] = this.leftBtnBgColor; + data['right_text'] = this.rightText; + data['right_text_color'] = this.rightTextColor; + data['right_btn_bg_color'] = this.rightBtnBgColor; + return data; + } +} diff --git a/lib/pages/favorites_page/notifier/favorites_page_notifier.dart b/lib/pages/favorites_page/notifier/favorites_page_notifier.dart new file mode 100644 index 0000000..7920fcb --- /dev/null +++ b/lib/pages/favorites_page/notifier/favorites_page_notifier.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +class FavoritesPageNotifier with ChangeNotifier { + /// 是否是编辑中 + bool isEditing = false; + + /// 搜索关键字 + String keyword; + + int selectIndex = 0; + + /// 用于区分是编辑还是搜索 + bool editingTypeTag = true; + + /// 用于区分是否修改 + // int changeVal = 0; + + /// 选中的下标 + void changeSelectIndex(int index){ + this.selectIndex = index; + // ++changeVal; + notifyListeners(); + } + + /// 编辑 + void editing() { + this.editingTypeTag = true; + this.isEditing = !isEditing; + // ++changeVal; + notifyListeners(); + } + + /// 搜索 + void search(String keyword) { + // if (!EmptyUtil.isEmpty(keyword)) { + this.editingTypeTag = false; + this.keyword = keyword; + // ++changeVal; + notifyListeners(); + // } + } + +} diff --git a/lib/register.dart b/lib/register.dart index 8708633..158ad42 100644 --- a/lib/register.dart +++ b/lib/register.dart @@ -1,6 +1,6 @@ import 'package:sharesdk_plugin/sharesdk_interface.dart'; import 'package:sharesdk_plugin/sharesdk_register.dart'; -import 'package:zhiying_base_widget/pages/favorite_page/favorite_page.dart'; + import 'package:zhiying_base_widget/pages/feedback_page/feedback_page.dart'; import 'package:zhiying_base_widget/pages/goods_details_page/goods_details_page.dart'; import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; @@ -52,6 +52,7 @@ import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income.d import 'package:zhiying_comm/util/defalut_widget_creater.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; +import 'pages/favorites_page/favorites_page.dart'; import 'pages/message_notice_page/message_notice_page.dart'; import 'pages/search_page/search_page.dart'; import 'pages/wallet_page/wallet_page.dart'; @@ -142,7 +143,7 @@ class BaseWidgetRegister { // 邀请好友 PageFactory.regist( 'pub.flutter.invite_friends', (model) => InvitedFriendsPage(model)); - PageFactory.regist('pub.flutter.fav', (model) => FavoritePage()); + /// 我的团队 PageFactory.regist('pub.flutter.my_team', (model) => TeamPage(model)); @@ -154,6 +155,9 @@ class BaseWidgetRegister { /// 消息中心 PageFactory.regist( 'pub.flutter.message_center', (model) => MessageNoticePage(model)); + + /// 我的收藏 + PageFactory.regist('pub.flutter.my_fav', (model) => FavoritesPage()); } // 注册控件 diff --git a/lib/widgets/favorites/dialog/favorites_dialog_widget.dart b/lib/widgets/favorites/dialog/favorites_dialog_widget.dart new file mode 100644 index 0000000..39ecb24 --- /dev/null +++ b/lib/widgets/favorites/dialog/favorites_dialog_widget.dart @@ -0,0 +1,75 @@ +import 'package:flutter/material.dart'; +import 'package:zhiying_base_widget/pages/favorites_page/model/favorites_style_model.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class FavoritesDialogWidget extends StatelessWidget { + ConfirmDialog styleModel; + + FavoritesDialogWidget({@required this.styleModel}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.transparent, + body: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: double.infinity, + padding: const EdgeInsets.only(top: 30, left: 17, right: 17, bottom: 12.5), + decoration: BoxDecoration(color: HexColor.fromHex(styleModel?.bgColor ?? '#FFFFFF'), borderRadius: BorderRadius.circular(8)), + margin: EdgeInsets.only(left: 46, right: 46), + child: Column( + children: [ + /// 标题 + Text(styleModel?.bgText, style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: HexColor.fromHex(styleModel?.bgTextColor ?? '#333333'))), + const SizedBox(height: 44), + Row( + children: [ + Flexible(flex: 1, child: _buildCustomerButtonWidget( + text: styleModel?.leftText ?? '我在想想', + textColor:styleModel?.leftTextColor ?? '#FF4242', + bgColor: styleModel?.leftBtnBgColor ?? '#FFFFFF', + borderColor: styleModel?.leftTextColor ?? '#FF4242', + callback: ()=> Navigator.maybePop(context, 0), + )), + const SizedBox(width: 14), + Flexible(flex: 1, child: _buildCustomerButtonWidget( + text: styleModel?.rightText ?? '确认删除', + textColor: styleModel?.rightTextColor ?? '#FFFFFF', + borderColor: styleModel?.rightTextColor ?? '#FFFFFF', + bgColor: styleModel?.rightBtnBgColor ?? '#FF4242', + callback: ()=> Navigator.maybePop(context, 1), + )), + ], + ) + ], + ), + ) + ], + ), + ); + } + + Widget _buildCustomerButtonWidget({String text, String textColor, String bgColor, String borderColor,GestureTapCallback callback, double height = 30}) { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: callback, + child: Container( + alignment: Alignment.center, + height: height, + width: double.infinity, + decoration: BoxDecoration( + color: HexColor.fromHex(bgColor), + borderRadius: BorderRadius.circular(height / 2), + border: Border.all(color: HexColor.fromHex(borderColor), width: 0.5), + ), + child: Text( + text ?? '', + style: TextStyle(color: HexColor.fromHex(textColor), fontSize: 13), + ), + ), + ); + } +} diff --git a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart new file mode 100644 index 0000000..4ca4489 --- /dev/null +++ b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart @@ -0,0 +1,173 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:flutter/material.dart'; +import 'package:meta/meta.dart'; +import 'package:zhiying_base_widget/widgets/favorites/goods_list/model/favorites_goods_list_model.dart'; +import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_model.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +import 'favorites_goods_list_repository.dart'; + +part 'favorites_goods_list_event.dart'; + +part 'favorites_goods_list_state.dart'; + +class FavoritesGoodsListBloc extends Bloc { + @override + FavoritesGoodsListState get initialState => FavoritesGoodsListInitial(); + + FavoritesGoodsListRepository repository; + + FavoritesGoodsListBloc(this.repository); + + @override + Stream mapEventToState( + FavoritesGoodsListEvent event, + ) async* { + /// 初始化数据 + if (event is FavoritesGoodsListInitEvent) { + yield* _mapInitEventToState(event); + } + + /// 下拉刷新 + if (event is FavoritesGoodsListOnRefreshEvent) { + yield* _mapOnRefreshEventToState(event); + } + + /// 上拉更多 + if (event is FavoritesGoodsListOnLoadEvent) { + yield* _mapOnLoadEventToState(event); + } + + /// 删除 + if (event is FavoritesGoodsListDeleteEvent) { + yield* _mapDeleteEventToState(event); + } + + /// 搜索 + if (event is FavoritesGoodsListSearchEvent) { + yield* _mapSearchEventToState(event); + } + + /// 单个商品选中 + if(event is FavoritesGoodsListSignGoodsSelectEvent){ + yield* _mapSelectSignEventToState(event); + } + + /// 所有商品选中 + if(event is FavoritesGoodsListGoodsSelectAllEvent){ + yield* _mapSelectAllEventToState(event); + } + + if(event is FavoritesGoodsListGoodsCancelAllEvent){ + yield* _mapCancelAllEventToState(event); + } + + // /// 切换样式 + // if (event is FavoritesGoodsListChangeStyleEvent) { + // yield* _mapChangeStyleEventToState(event); + // } + } + + /// 初始化数据 + Stream _mapInitEventToState(FavoritesGoodsListInitEvent event) async* { + var result = await repository.fetchInit(); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesGoodsListLoadedState(dataModel: result); + } else { + yield FavoritesGoodsListInitErrorState(); + } + } + + /// 下拉刷新 + Stream _mapOnRefreshEventToState(FavoritesGoodsListOnRefreshEvent event) async* { + var result = await repository.fetchRefresh(); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesGoodsListRefreshSuccessState(); + yield FavoritesGoodsListLoadedState(dataModel: result); + } else { + yield FavoritesGoodsListRefreshErrorState(); + yield FavoritesGoodsListErrorState(); + } + } + + /// 上拉更多 + Stream _mapOnLoadEventToState(FavoritesGoodsListOnLoadEvent event) async* { + var result = await repository.fetchLoad(); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesGoodsListLoadSuccessState(); + yield FavoritesGoodsListLoadedState(dataModel: result); + } else { + yield FavoritesGoodsListLoadErrorState(); + yield FavoritesGoodsListErrorState(); + } + } + + /// 删除 + Stream _mapDeleteEventToState(FavoritesGoodsListDeleteEvent event) async* { + int length = repository.getSelectLength(); + if(length > 0) { + var result = await repository.delete(); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesGoodsListLoadedState(dataModel: result); + } else { + yield FavoritesGoodsListErrorState(); + } + }else{ + yield FavoritesGoodsListNotSelectState(); + } + } + + /// 搜索 + Stream _mapSearchEventToState(FavoritesGoodsListSearchEvent event) async* { + var result = await repository.search(event.keyword); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesGoodsListLoadedState(dataModel: result); + } else { + yield FavoritesGoodsListInitErrorState(); + } + } + + /// 所有商品选中 + Stream _mapSelectAllEventToState(FavoritesGoodsListGoodsSelectAllEvent event) async*{ + var result = await repository.selectAllData(); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesGoodsListLoadedState(dataModel: result); + } else { + yield FavoritesGoodsListErrorState(); + } + } + + /// 商品的全部取消 + Stream _mapCancelAllEventToState(FavoritesGoodsListGoodsCancelAllEvent event) async*{ + var result = await repository.cancelSelectAllData(); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesGoodsListLoadedState(dataModel: result); + } else { + yield FavoritesGoodsListErrorState(); + } + } + + /// 单个商品选中 + Stream _mapSelectSignEventToState(FavoritesGoodsListSignGoodsSelectEvent event) async*{ + var result = await repository.signSelectData(event.index); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesGoodsListLoadedState(dataModel: result); + } else { + yield FavoritesGoodsListErrorState(); + } + } + + + + // /// 切换样式 + // Stream _mapChangeStyleEventToState(FavoritesGoodsListChangeStyleEvent event) async* { + // var result = await repository.fetchInit(); + // if (!EmptyUtil.isEmpty(result)) { + // yield FavoritesGoodsListLoadedState(dataModel: result); + // } else { + // yield FavoritesGoodsListInitErrorState(); + // } + // } +} diff --git a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart new file mode 100644 index 0000000..d687a76 --- /dev/null +++ b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart @@ -0,0 +1,39 @@ +part of 'favorites_goods_list_bloc.dart'; + +@immutable +abstract class FavoritesGoodsListEvent {} + + +/// 初始化数据 +class FavoritesGoodsListInitEvent extends FavoritesGoodsListEvent {} + +/// 下拉刷新 +class FavoritesGoodsListOnRefreshEvent extends FavoritesGoodsListEvent {} + +/// 上拉更多 +class FavoritesGoodsListOnLoadEvent extends FavoritesGoodsListEvent {} + +/// 关键字搜索 +class FavoritesGoodsListSearchEvent extends FavoritesGoodsListEvent { + final String keyword; + FavoritesGoodsListSearchEvent(this.keyword); +} + +/// 删除 +class FavoritesGoodsListDeleteEvent extends FavoritesGoodsListEvent {} + +/// 切换样式 +class FavoritesGoodsListChangeStyleEvent extends FavoritesGoodsListEvent{} + +/// 商品的当个选中 +class FavoritesGoodsListSignGoodsSelectEvent extends FavoritesGoodsListEvent{ + // final FavoritesGoodsListItemModel model; + final int index; + FavoritesGoodsListSignGoodsSelectEvent(this.index); +} + +/// 商品的全选 +class FavoritesGoodsListGoodsSelectAllEvent extends FavoritesGoodsListEvent{} + +/// 商品的全部取消 +class FavoritesGoodsListGoodsCancelAllEvent extends FavoritesGoodsListEvent{} \ No newline at end of file diff --git a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart new file mode 100644 index 0000000..42d3572 --- /dev/null +++ b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart @@ -0,0 +1,161 @@ +import 'package:flutter/cupertino.dart'; +import 'package:zhiying_base_widget/widgets/favorites/goods_list/model/favorites_goods_list_model.dart'; +import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_model.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class FavoritesGoodsListRepository { + String type; + + final int _MAX = 5; + int _currentPage = 1; + bool _hasMoreData = true; + + FavoritesGoodsListDataModel _oldData = new FavoritesGoodsListDataModel(); + Map _selectIndex = {}; + + FavoritesGoodsListRepository({this.type = 'all'}); + + String keyword; + + /// 返回选中的商品长度 + int getSelectLength() { + return _selectIndex.length; + } + + /// 选中所有 + Future selectAllData() async { + _selectIndex.clear(); + int index = 0; + _oldData.lists.forEach((element) { + element.isSelect = true; + _selectIndex[index] = index; + ++index; + }); + _oldData.isAllSelect = true; + return _oldData; + } + + /// 单个选中状态 + Future signSelectData(final int selectIndex) async { + _oldData.lists[selectIndex].isSelect = !_oldData.lists[selectIndex].isSelect; + + if (_oldData.lists[selectIndex].isSelect) { + // 新增 + _selectIndex[selectIndex] = selectIndex; + } else { + // 移除 + _selectIndex.remove(selectIndex); + } + _oldData.isAllSelect = false; + if (_selectIndex.length == _oldData.lists.length) { + _oldData.isAllSelect = true; + } + return _oldData; + } + + /// 取消选中所有 or 重置选中状态 + Future cancelSelectAllData() async { + _selectIndex.clear(); + _oldData.lists.forEach((element) { + element.isSelect = false; + }); + _oldData.isAllSelect = false; + return _oldData; + } + + /// 关键字搜索 + Future search(String keyword) async { + try { + _selectIndex.clear(); + _oldData.lists.clear(); + _currentPage = 1; + _hasMoreData = true; + + this.keyword = keyword; + return _baseRequest(); + } catch (e, s) { + Logger.error(e, s); + } + return null; + } + + /// 删除数据 + Future delete() async { + try { + // Logger.log('select Index length = ${_selectIndex.length}'); + if (_selectIndex.length > 0) { + List gids = []; + _selectIndex.forEach((key, value) { + gids.add(_oldData.lists[value].goodId); + }); + var result = await NetUtil.post('/api/v1/user/myfav/delete', params: {'gids': gids}, method: NetMethod.POST); + if (NetUtil.isSuccess(result)) { + List tempList = []; + // TODO 这里有问题:移除删除 + for (int i = 0; i < _oldData.lists.length; i++) { + if (!_selectIndex.containsKey(i)) { + tempList.add(_oldData.lists[i]); + } + } + _oldData.lists.clear(); + _selectIndex.clear(); + _oldData.isAllSelect = false; + _oldData.lists = tempList; + return _oldData; + } + } + } catch (e, s) { + Logger.error(e, s); + } + return null; + } + + /// 初始化请求 + Future fetchInit() async { + _currentPage = 1; + _hasMoreData = true; + _oldData?.lists?.clear(); + _selectIndex.clear(); + _oldData.isAllSelect = false; + return _baseRequest(); + } + + /// 下拉刷新 + Future fetchRefresh() async { + return fetchInit(); + } + + /// 上拉更多 + Future fetchLoad() async { + if (_hasMoreData) { + return _baseRequest(); + } + return null; + } + + /// 基础请求 + Future _baseRequest() async { + try { + var result; + if(EmptyUtil.isEmpty(keyword)) { + result = await NetUtil.post('/api/v1/user/myfav/$type?page=${_currentPage.toString()}', params: {}, method: NetMethod.GET); + }else{ + result = await NetUtil.post('/api/v1/user/myfav/s', params: {'keyword': keyword}, method: NetMethod.POST); + } + if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { + List data = result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]; + data.forEach((element) { + _oldData.lists.add(FavoritesGoodsListItemModel.fromJson(element)); + }); + ++_currentPage; + _hasMoreData = true; + // _hasMoreData = data.length >= _MAX ? true : false; + return _oldData; + } + _hasMoreData = false; + } catch (e, s) { + Logger.error(e, s); + } + return null; + } +} diff --git a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_state.dart b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_state.dart new file mode 100644 index 0000000..fc70477 --- /dev/null +++ b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_state.dart @@ -0,0 +1,35 @@ +part of 'favorites_goods_list_bloc.dart'; + +@immutable +abstract class FavoritesGoodsListState {} + +/// 初始化状态(骨架图) +class FavoritesGoodsListInitial extends FavoritesGoodsListState {} + +/// 初始化失败状态(空数据) +class FavoritesGoodsListInitErrorState extends FavoritesGoodsListState {} + +/// 下拉刷新失败状态 +class FavoritesGoodsListRefreshErrorState extends FavoritesGoodsListState {} + +/// 下拉刷新成功状态 +class FavoritesGoodsListRefreshSuccessState extends FavoritesGoodsListState {} + +/// 上拉更多失败状态 +class FavoritesGoodsListLoadErrorState extends FavoritesGoodsListState {} + +/// 上拉更多成功状态 +class FavoritesGoodsListLoadSuccessState extends FavoritesGoodsListState {} + +/// 数据加载成功 +class FavoritesGoodsListLoadedState extends FavoritesGoodsListState { + // List dataModel; + FavoritesGoodsListDataModel dataModel; + FavoritesGoodsListLoadedState({@required this.dataModel}); +} + +/// 没选中 +class FavoritesGoodsListNotSelectState extends FavoritesGoodsListState{} + +/// 未知错误 +class FavoritesGoodsListErrorState extends FavoritesGoodsListState {} diff --git a/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart b/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart new file mode 100644 index 0000000..7f3bb6c --- /dev/null +++ b/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart @@ -0,0 +1,325 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; +import 'package:zhiying_base_widget/dialog/tip_dialog/tip_dialog.dart'; +import 'package:zhiying_base_widget/pages/favorites_page/model/favorites_style_model.dart'; +import 'package:zhiying_base_widget/pages/favorites_page/notifier/favorites_page_notifier.dart'; +import 'package:zhiying_base_widget/widgets/favorites/dialog/favorites_dialog_widget.dart'; +import 'package:zhiying_base_widget/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart'; +import 'package:zhiying_base_widget/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart'; +import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_item_single.dart'; +import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_style_model.dart'; +import 'package:zhiying_base_widget/widgets/home/home_goods/skeleton/home_goods_sk.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:provider/provider.dart'; +import 'package:fluttertoast/fluttertoast.dart'; + +import 'model/favorites_goods_list_model.dart'; + +class FavoritesGoodsListWidget extends StatelessWidget { + FavoritesStyleModel model; + String type; + int currentIndex; + + FavoritesGoodsListWidget({@required this.model, @required this.type, this.currentIndex = 0}); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (_) => FavoritesGoodsListBloc(FavoritesGoodsListRepository(type: type)), + child: _FavoritesGoodsListWidgetContainer(model, currentIndex), + ); + } +} + +class _FavoritesGoodsListWidgetContainer extends StatefulWidget { + FavoritesStyleModel styleModel; + int currentIndex; + + _FavoritesGoodsListWidgetContainer(this.styleModel, this.currentIndex); + + @override + __FavoritesGoodsListWidgetContainerState createState() => __FavoritesGoodsListWidgetContainerState(); +} + +class __FavoritesGoodsListWidgetContainerState extends State<_FavoritesGoodsListWidgetContainer> with AutomaticKeepAliveClientMixin { + RefreshController _refreshController; + + // 是否编辑中 + bool isEditing = false; + int lastChangeVal = -1; + + /// 下拉刷新 + void _onRefresh() async { + BlocProvider.of(context).add(FavoritesGoodsListOnRefreshEvent()); + } + + /// 上拉更多 + void _onLoad() async { + BlocProvider.of(context).add(FavoritesGoodsListOnLoadEvent()); + } + + /// 商品点击选中 + void _onClickGoods(int index){ + BlocProvider.of(context).add(FavoritesGoodsListSignGoodsSelectEvent(index)); + } + + /// 全选 + void _onClickAllSelecct(FavoritesGoodsListDataModel dataModel) { + + if(!dataModel.isAllSelect) { + BlocProvider.of(context).add(FavoritesGoodsListGoodsSelectAllEvent()); + }else{ + BlocProvider.of(context).add(FavoritesGoodsListGoodsCancelAllEvent()); + } + } + + /// 点击删除 + void _onClickDelete(ConfirmDialog styleModel) async { + + // + var result = await showDialog(context: context, child: FavoritesDialogWidget(styleModel: styleModel,)); + if(result == 1){ + BlocProvider.of(context).add(FavoritesGoodsListDeleteEvent()); + } + } + + @override + bool get wantKeepAlive => true; + + @override + void initState() { + _refreshController = RefreshController(); + BlocProvider.of(context).add(FavoritesGoodsListInitEvent()); + super.initState(); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + FavoritesPageNotifier favoritesPageNotifier = Provider.of(context); + + if (null != favoritesPageNotifier) { + isEditing = favoritesPageNotifier.isEditing; + if(favoritesPageNotifier.editingTypeTag) { + + // BlocProvider.of(context).add(FavoritesGoodsListGoodsCancelAllEvent()); + }else{ + // if(favoritesPageNotifier.selectIndex == widget.currentIndex) { + BlocProvider.of(context).add(FavoritesGoodsListSearchEvent(favoritesPageNotifier?.keyword)); + // } + } + } + } + + @override + void dispose() { + _refreshController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Listener( + onPointerDown: (down)=> RouterUtil.hideKeyboard(context), + child: Container( + color: HexColor.fromHex('#F9F9F9'), + child: BlocConsumer( + listener: (context, state) {}, + buildWhen: (prev, current) { + if (current is FavoritesGoodsListRefreshSuccessState) { + _refreshController?.refreshCompleted(resetFooterState: true); + return false; + } + if (current is FavoritesGoodsListRefreshErrorState) { + _refreshController?.refreshFailed(); + return false; + } + if (current is FavoritesGoodsListLoadSuccessState) { + _refreshController?.loadComplete(); + return false; + } + if (current is FavoritesGoodsListLoadErrorState) { + _refreshController?.loadNoData(); + return false; + } + if (current is FavoritesGoodsListErrorState) { + return false; + } + if(current is FavoritesGoodsListNotSelectState){ + Fluttertoast.showToast(msg: '请选择需要删除的商品~'); + return false; + } + return true; + }, + builder: (context, state) { + /// 初始化失败,空数据 + if (state is FavoritesGoodsListInitErrorState) { + return _buildEmptyWidget(widget?.styleModel); + } + + /// 数据加载成功 + if (state is FavoritesGoodsListLoadedState) { + // Logger.log('__FavoritesGoodsListWidgetContainerState ==== 刷新 size = ${state?.dataModel?.lists?.length}'); + return _buildGoodsListWidget(widget?.styleModel, state?.dataModel); + } + + /// 骨架图 + return _buildSkeletonWidget(widget?.styleModel); + }, + ), + ), + ); + } + + /// 有数据返回 + Widget _buildGoodsListWidget(FavoritesStyleModel styleModel, FavoritesGoodsListDataModel dataModel) { + + + /// 如果数据删除了,则返回空视图 + int length = dataModel?.lists?.length ?? 0; + if(length == 0) return _buildEmptyWidget(styleModel); + + return Stack( + children: [ + /// 数据 + SmartRefresher( + controller: _refreshController, + onRefresh: _onRefresh, + onLoading: _onLoad, + enablePullUp: true, + enablePullDown: true, + child: ListView.builder( + padding: EdgeInsets.only(top: 7.5, left: 12.5, right: isEditing ? 0 : 12.5), + itemCount: dataModel.lists.length, + itemBuilder: (context, index) { + FavoritesGoodsListItemModel item = dataModel.lists[index]; + return Row( + children: [ + Visibility( + visible: isEditing , + child: GestureDetector( + onTap: ()=> _onClickGoods(index), + behavior: HitTestBehavior.opaque, + child: Container( + height: 20, + width: 20, + margin: const EdgeInsets.only(right: 8), + child: CachedNetworkImage( + imageUrl: item.isSelect ? styleModel?.editLeftConfirmIcon : styleModel?.editLeftNoConfirmIcon, + ), + ), + ), + ), + Expanded( + child: HomeGoodsItemSingle( + item, + HomeGoodsStyleModel()..listStyle = styleModel?.listStyle, + marginBottom: 0, + marginLeft: 0, + marginRight: 0, + marginTop: 0, + ), + ) + ], + ); + }), + ), + + /// 编辑 + _buildEditrWidget(widget?.styleModel, dataModel), + ], + ); + } + + /// 编辑的底部Widget + Widget _buildEditrWidget(FavoritesStyleModel styleModel, FavoritesGoodsListDataModel dataModel) { + return Align( + alignment: Alignment.bottomCenter, + child: Visibility( + visible: isEditing , + child: Container( + padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 15.5, bottom: 15.5), + width: double.infinity, + decoration: BoxDecoration( + color: HexColor.fromHex(styleModel?.bottom?.bgColor ?? '#FFFFFF'), borderRadius: BorderRadius.only(topRight: Radius.circular(10), topLeft: Radius.circular(10))), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () => _onClickAllSelecct(dataModel), + behavior: HitTestBehavior.opaque, + child: Row( + children: [ + Visibility( + visible: dataModel?.isAllSelect ?? false, + replacement: Container( + width: 20, + height: 20, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), border: Border.all(color: HexColor.fromHex('#DCDCDC'), width: 0.5)), + ), + child: Container( + height: 20, + width: 20, + child: CachedNetworkImage(imageUrl: styleModel?.editLeftConfirmIcon ?? '',), + ), + ), + const SizedBox(width: 8), + Text( + styleModel?.bottom?.leftText ?? '全选', + style: TextStyle( + fontSize: 15, + color: HexColor.fromHex(styleModel?.bottom?.leftColor ?? '#333333'), + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + GestureDetector( + onTap: () => _onClickDelete(styleModel?.confirmDialog), + behavior: HitTestBehavior.opaque, + child: Text( + styleModel?.bottom?.rightText ?? '删除', + style: TextStyle( + fontSize: 15, + color: HexColor.fromHex(styleModel?.bottom?.rightColor ?? '#FF4242'), + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ), + ); + } + + /// 空数据 + Widget _buildEmptyWidget(FavoritesStyleModel styleModel) { + return SmartRefresher( + controller: _refreshController, + onRefresh: _onRefresh, + enablePullDown: true, + enablePullUp: false, + child: Column( + children: [ + const SizedBox(height: 80), + CachedNetworkImage(imageUrl: styleModel?.tabItemNotFoundImg ?? '', width: 188), + const SizedBox(height: 22), + Text( + '暂时没有商品噢\n快去浏览收藏吧', + style: TextStyle(fontSize: 15, color: HexColor.fromHex('#999999')), + ) + ], + ), + ); + } + + /// 骨架图 + Widget _buildSkeletonWidget(FavoritesStyleModel styleModel) { + return HomeGoodsSkeleton(); + } +} diff --git a/lib/widgets/favorites/goods_list/model/favorites_goods_list_model.dart b/lib/widgets/favorites/goods_list/model/favorites_goods_list_model.dart new file mode 100644 index 0000000..4f5977f --- /dev/null +++ b/lib/widgets/favorites/goods_list/model/favorites_goods_list_model.dart @@ -0,0 +1,37 @@ +import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_model.dart'; + +// ignore: must_be_immutable + +class FavoritesGoodsListDataModel { + // 是否全选 + bool isAllSelect = false; + + List lists = []; + + // FavoritesGoodsListDataModel({this.isEditing, this.isAllSelect, this.lists }); + FavoritesGoodsListDataModel(); + + FavoritesGoodsListDataModel.fromJson(Map json) { + isAllSelect = json['isAllSelect'] ?? false; + if(json['data'] != null){ + json['data'].forEach((v){ + lists.add(new FavoritesGoodsListItemModel.fromJson(v)); + }); + } + } +} + +class FavoritesGoodsListItemModel extends HomeGoodsModel { + bool isSelect; + + FavoritesGoodsListItemModel.fromJson(Map json) { + super.fromJson(json); + isSelect = json['isSelect'] ?? false; + } + + Map toJson() { + final Map data = super.toJson(); + data['isSelect'] = this.isSelect; + return data; + } +} diff --git a/lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart b/lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart index a73b0b1..1852fee 100644 --- a/lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart +++ b/lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart @@ -27,11 +27,22 @@ class GoodsDetailsFooterBloc extends Bloc _mapInitEventToState(GoodsDetailsFooterInitEvent event) async* { - var result = await repository.fetchParentData(event.model); + var result = await repository.fetchParentData(event?.model); if (!EmptyUtil.isEmpty(result)) { print('result = ${result.toString()}'); yield GoodsDetailsFooterLoadedState(model: result); @@ -42,10 +53,20 @@ class GoodsDetailsFooterBloc extends Bloc _mapCollectEventToState(GoodsDetailsFooterCollectEvent event) async* { - var result = await repository.fetchCollect(); + var result = await repository.fetchCollect(event?.model); if (!EmptyUtil.isEmpty(result)) yield GoodsDetailsFooterLoadedState(model: result); else yield GoodsDetailsFooterErrorState(); } + + /// 取消收藏 + Stream _mapDeleteCollectEventToState(GoodsDetailsFooterDeleteCollectEvent event ) async*{ + var result = await repository.fetchDeleteCollect(event?.model); + if(!EmptyUtil.isEmpty(result)) + yield GoodsDetailsFooterLoadedState(model: result); + else + yield GoodsDetailsFooterErrorState(); + } + } diff --git a/lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart b/lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart index 6f9f44b..185e857 100644 --- a/lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart +++ b/lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart @@ -19,5 +19,20 @@ class GoodsDetailsFooterInitEvent extends GoodsDetailsFooterEvent { /// 点击收藏 class GoodsDetailsFooterCollectEvent extends GoodsDetailsFooterEvent { + final Map model; + + GoodsDetailsFooterCollectEvent({@required this.model}); + + @override + List get props => [this.model]; +} +/// 取消收藏 +class GoodsDetailsFooterDeleteCollectEvent extends GoodsDetailsFooterEvent { + final Map model; + + GoodsDetailsFooterDeleteCollectEvent({@required this.model}); + + @override + List get props => [this.model]; } diff --git a/lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart b/lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart index e34a8c5..f635d0c 100644 --- a/lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart +++ b/lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart @@ -4,18 +4,50 @@ import 'package:zhiying_base_widget/widgets/goods_details/footer/model/goods_det import 'package:zhiying_comm/zhiying_comm.dart'; class GoodsDetailsFooterRepository { + + GoodsDetailsFooterModel _oldmodel; + /// 初始化数据 Future fetchParentData(final Map model) async { try { - return GoodsDetailsFooterModel.fromJson(jsonDecode(model['data'])); - } catch (e) { - Logger.log('GoodsDetailsFooterRepository e = $e'); + GoodsDetailsFooterModel data = GoodsDetailsFooterModel.fromJson(jsonDecode(model['data'])); + _oldmodel = data; + return data; + } catch (e, s) { + Logger.error(e, s); } return null; } /// 点击收藏 - Future fetchCollect() async{ + Future fetchCollect(final Map model) async { + try { + if (!EmptyUtil.isEmpty(model)) { + var result = await NetUtil.post('/api/v1/user/myfav', params: model, method: NetMethod.POST); + if(NetUtil.isSuccess(result)){ + _oldmodel.isFav = '1'; + return _oldmodel; + } + } + } catch (e, s) { + Logger.error(e, s); + } + return null; + } + + /// 取消收藏 + Future fetchDeleteCollect(final Map model) async{ + try{ + if(!EmptyUtil.isEmpty(model)){ + var result = await NetUtil.post('/api/v1/user/myfav/delete', params: {'gids':[model['good_id']]}, method: NetMethod.POST); + if(NetUtil.isSuccess(result)){ + _oldmodel.isFav = '0'; + return _oldmodel; + } + } + }catch(e, s){ + Logger.error(e,s); + } return null; } diff --git a/lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart b/lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart index ae3ae2d..99d7817 100644 --- a/lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart +++ b/lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart @@ -1,15 +1,15 @@ part of 'goods_details_footer_bloc.dart'; -abstract class GoodsDetailsFooterState extends Equatable { +abstract class GoodsDetailsFooterState { const GoodsDetailsFooterState(); - @override - List get props => []; + // @override + // List get props => []; } class GoodsDetailsFooterInitial extends GoodsDetailsFooterState { - @override - List get props => []; + // @override + // List get props => []; } /// 数据加载完毕 @@ -18,8 +18,8 @@ class GoodsDetailsFooterLoadedState extends GoodsDetailsFooterState { GoodsDetailsFooterLoadedState({@required this.model}); - @override - List get props => [this.model]; + // @override + // List get props => [this.model]; } /// 数据加载出错 diff --git a/lib/widgets/goods_details/footer/goods_details_footer_widget.dart b/lib/widgets/goods_details/footer/goods_details_footer_widget.dart index dcf400d..0c8c826 100644 --- a/lib/widgets/goods_details/footer/goods_details_footer_widget.dart +++ b/lib/widgets/goods_details/footer/goods_details_footer_widget.dart @@ -75,7 +75,14 @@ class _GooddsDetailsFooterContainerState } /// 收藏 - void _collectOnClick() {} + void _collectOnClick(GoodsDetailsFooterModel model) { + bool isCollect = model.isFav == '0'; + if(isCollect){ // 收藏 + BlocProvider.of(context).add(GoodsDetailsFooterCollectEvent(model: model?.favArgs?.toJson())); + }else{ // 取消收藏 + BlocProvider.of(context).add(GoodsDetailsFooterDeleteCollectEvent(model: model?.favArgs?.toJson())); + } + } /// 分享 void _shareOnClick(GoodsDetailsFooterModel model) async { @@ -221,13 +228,13 @@ class _GooddsDetailsFooterContainerState )), GestureDetector( behavior: HitTestBehavior.opaque, - onTap: () => _collectOnClick(), + onTap: () => _collectOnClick(model), child: Padding( padding: const EdgeInsets.only(right: 0), child: _getCustomWidget( model?.collect ?? '收藏', model?.collect_color ?? '999999', - model?.collect_icon ?? ''))) + model?.isFav == '0' ? model?.collect_icon ?? '' : model?.collected_icon ?? ''))) ], ); } diff --git a/lib/widgets/goods_details/footer/model/goods_details_footer_model.dart b/lib/widgets/goods_details/footer/model/goods_details_footer_model.dart index 1ba8d57..25c7224 100644 --- a/lib/widgets/goods_details/footer/model/goods_details_footer_model.dart +++ b/lib/widgets/goods_details/footer/model/goods_details_footer_model.dart @@ -2,6 +2,7 @@ class GoodsDetailsFooterModel { String collect; String collect_color; String collect_icon; + String collected_icon; String home; String home_color; String home_icon; @@ -18,28 +19,46 @@ class GoodsDetailsFooterModel { String share_value; String self_buy_value; - GoodsDetailsFooterModel( - {this.collect, - this.collect_color, - this.collect_icon, - this.home, - this.home_color, - this.home_icon, - this.save_earn, - this.save_earn_bg1_color, - this.save_earn_bg2_color, - this.save_earn_color, - this.save_earn_val_color, - this.share_earn, - this.share_earn_bg1_color, - this.share_earn_bg2_color, - this.share_earn_color, - this.share_earn_val_color, - this.share_value, - this.self_buy_value}); + String isFav; + String buyUrl; + String shareUrl; + FavArgs favArgs; + ShareUrlArgs shareUrlArgs; + + GoodsDetailsFooterModel({ + this.buyUrl, + this.favArgs, + this.isFav, + this.shareUrl, + this.shareUrlArgs, + this.collect, + this.collect_color, + this.collect_icon, + this.home, + this.home_color, + this.home_icon, + this.save_earn, + this.save_earn_bg1_color, + this.save_earn_bg2_color, + this.save_earn_color, + this.save_earn_val_color, + this.share_earn, + this.share_earn_bg1_color, + this.share_earn_bg2_color, + this.share_earn_color, + this.share_earn_val_color, + this.share_value, + this.self_buy_value, + this.collected_icon, + }); factory GoodsDetailsFooterModel.fromJson(Map json) { return GoodsDetailsFooterModel( + isFav: json['is_fav'], + buyUrl: json['buy_url'], + shareUrl: json['share_url'], + favArgs: json['fav_args'] != null ? new FavArgs.fromJson(json['fav_args']) : null, + shareUrlArgs: json['share_url_args'] != null ? new ShareUrlArgs.fromJson(json['share_url_args']) : null, collect: json['collect'], collect_color: json['collect_color'], collect_icon: json['collect_icon'], @@ -58,6 +77,7 @@ class GoodsDetailsFooterModel { share_earn_val_color: json['share_earn_val_color'], share_value: json['share_value'], self_buy_value: json['self_buy_value'], + collected_icon: json['collected_icon'], ); } @@ -81,6 +101,120 @@ class GoodsDetailsFooterModel { data['share_earn_val_color'] = this.share_earn_val_color; data['share_value'] = this.share_value; data['self_buy_value'] = this.self_buy_value; + data['collected_icon'] = this.collected_icon; + + data['is_fav'] = this.isFav; + data['buy_url'] = this.buyUrl; + data['share_url'] = this.shareUrl; + if (this.favArgs != null) { + data['fav_args'] = this.favArgs.toJson(); + } + if (this.shareUrlArgs != null) { + data['share_url_args'] = this.shareUrlArgs.toJson(); + } + + return data; + } +} + +class FavArgs { + String provider; + String providerName; + String goodId; + String goodImage; + String goodTitle; + String shopName; + String coupon; + String couponUrl; + String commission; + String marketPrice; + String currentPrice; + String inorderCount; + Null detailData; + + FavArgs( + {this.provider, + this.providerName, + this.goodId, + this.goodImage, + this.goodTitle, + this.shopName, + this.coupon, + this.couponUrl, + this.commission, + this.marketPrice, + this.currentPrice, + this.inorderCount, + this.detailData}); + + FavArgs.fromJson(Map json) { + provider = json['provider']; + providerName = json['provider_name']; + goodId = json['good_id']; + goodImage = json['good_image']; + goodTitle = json['good_title']; + shopName = json['shop_name']; + coupon = json['coupon']; + couponUrl = json['coupon_url']; + commission = json['commission']; + marketPrice = json['market_price']; + currentPrice = json['current_price']; + inorderCount = json['inorder_count']; + detailData = json['detail_data']; + } + + Map toJson() { + final Map data = new Map(); + data['provider'] = this.provider; + data['provider_name'] = this.providerName; + data['good_id'] = this.goodId; + data['good_image'] = this.goodImage; + data['good_title'] = this.goodTitle; + data['shop_name'] = this.shopName; + data['coupon'] = this.coupon; + data['coupon_url'] = this.couponUrl; + data['commission'] = this.commission; + data['market_price'] = this.marketPrice; + data['current_price'] = this.currentPrice; + data['inorder_count'] = this.inorderCount; + data['detail_data'] = this.detailData; + return data; + } +} + +class ShareUrlArgs { + String buyUrl; + String coupon; + String couponPrice; + String marketPrice; + String posterImage; + String selfbuyCommission; + String title; + String type; + + ShareUrlArgs({this.buyUrl, this.coupon, this.couponPrice, this.marketPrice, this.posterImage, this.selfbuyCommission, this.title, this.type}); + + ShareUrlArgs.fromJson(Map json) { + buyUrl = json['buy_url']; + coupon = json['coupon']; + couponPrice = json['coupon_price']; + marketPrice = json['market_price']; + posterImage = json['poster_image']; + selfbuyCommission = json['selfbuy_commission']; + title = json['title']; + type = json['type']; + } + + Map toJson() { + final Map data = new Map(); + data['buy_url'] = this.buyUrl; + data['coupon'] = this.coupon; + data['coupon_price'] = this.couponPrice; + data['market_price'] = this.marketPrice; + data['poster_image'] = this.posterImage; + data['selfbuy_commission'] = this.selfbuyCommission; + data['title'] = this.title; + data['type'] = this.type; return data; } } diff --git a/lib/widgets/home/home_goods/home_goods_item_single.dart b/lib/widgets/home/home_goods/home_goods_item_single.dart index edcdb20..48bf7fe 100644 --- a/lib/widgets/home/home_goods/home_goods_item_single.dart +++ b/lib/widgets/home/home_goods/home_goods_item_single.dart @@ -14,8 +14,12 @@ class HomeGoodsItemSingle extends StatelessWidget { final HomeGoodsModel goods; final HomeGoodsStyleModel style; Map data; + final double marginLeft; + final double marginRight; + final double marginTop; + final double marginBottom; - HomeGoodsItemSingle(this.goods, this.style, {Key key, this.data}) + HomeGoodsItemSingle(this.goods, this.style, {Key key, this.data, this.marginBottom = 4, this.marginTop = 4, this.marginLeft= 12.5, this.marginRight = 12.5}) : super(key: key) { if (this.data != null && this.data.containsKey('data')) { String data = this.data['data']; @@ -36,7 +40,7 @@ class HomeGoodsItemSingle extends StatelessWidget { return GestureDetector( onTap: () => _onJumpGoodsDetails(context, goods), child: Container( - margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 4, bottom: 4), + margin: EdgeInsets.only(left: marginLeft, right: marginRight, top: marginTop, bottom: marginBottom), padding: EdgeInsets.all(7.5), decoration: BoxDecoration( color: Colors.white, diff --git a/lib/widgets/home/home_goods/models/home_goods_model.dart b/lib/widgets/home/home_goods/models/home_goods_model.dart index d180c9c..563b860 100644 --- a/lib/widgets/home/home_goods/models/home_goods_model.dart +++ b/lib/widgets/home/home_goods/models/home_goods_model.dart @@ -44,6 +44,21 @@ class HomeGoodsModel extends Equatable { detailData = json['detail_data']; } + void fromJson(Map json) { + provider = json['provider']; + providerName = json['provider_name']; + goodId = json['good_id']; + goodImage = json['good_image']; + goodTitle = json['good_title']; + shopName = json['shop_name']; + coupon = json['coupon']; + commission = json['commission']; + marketPrice = json['market_price']; + currentPrice = json['current_price']; + inorderCount = json['inorder_count']; + detailData = json['detail_data']; + } + Map toJson() { final Map data = new Map(); data['provider'] = this.provider; From 5216f0068b4c1f85a06bb67f74dfd787f812e2ee Mon Sep 17 00:00:00 2001 From: PH2 <1293456824@qq.com> Date: Thu, 29 Oct 2020 14:47:08 +0800 Subject: [PATCH 2/6] =?UTF-8?q?1=E3=80=81=E5=A4=84=E7=90=86=E4=BA=86?= =?UTF-8?q?=E5=95=86=E5=93=81=E8=AF=A6=E6=83=85=E6=B2=A1=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=E6=8A=A5=E9=94=99=202=E3=80=81?= =?UTF-8?q?=E5=A4=84=E7=90=86=E4=BA=86=E6=B6=88=E6=81=AF=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E7=9A=84=E9=83=A8=E5=88=86=E6=9C=BA=E5=AD=90=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=B8=8D=E5=85=A8=E7=9A=84=E9=97=AE=E9=A2=98=203=E3=80=81?= =?UTF-8?q?=E7=BB=99=E7=99=BD=E8=89=B2=E7=9A=84=E9=A1=B5=E9=9D=A2=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=A0=8F=E5=AD=97=E4=BD=93=E6=94=B9=E6=88=90=E9=BB=91?= =?UTF-8?q?=E8=89=B2=204=E3=80=81=E6=88=91=E7=9A=84=E4=BA=BA=E8=84=89?= =?UTF-8?q?=EF=BC=8C=E5=A4=B4=E5=83=8F=E5=9C=86=E5=BD=A2=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/favorites_page/favorites_page.dart | 5 +++++ .../message_notice_page.dart | 3 ++- .../team_details_page/team_details_page.dart | 1 + .../detail_img/goods_details_img.dart | 21 ++++++++++++------- .../team/appbar/team_app_bar_widget.dart | 1 + .../team/recommend/team_recommend_widget.dart | 15 +++++++------ 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/lib/pages/favorites_page/favorites_page.dart b/lib/pages/favorites_page/favorites_page.dart index 19ff195..d7364a7 100644 --- a/lib/pages/favorites_page/favorites_page.dart +++ b/lib/pages/favorites_page/favorites_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:tab_indicator_styler/tab_indicator_styler.dart'; import 'package:zhiying_base_widget/pages/favorites_page/bloc/favorites_bloc.dart'; import 'package:zhiying_base_widget/pages/favorites_page/bloc/favorites_repository.dart'; @@ -14,6 +15,9 @@ import 'package:zhiying_comm/util/router_util.dart'; import 'model/favorites_style_model.dart'; import 'notifier/favorites_page_notifier.dart'; +/// +/// 收藏夹 +/// class FavoritesPage extends StatelessWidget { @override Widget build(BuildContext context) { @@ -220,6 +224,7 @@ class _FavoritesPageContainerState extends State<_FavoritesPageContainer> with T Widget _buildAppBarWidget(FavoritesStyleModel model) { return AppBar( backgroundColor: HexColor.fromHex(model?.appBarBgColor ?? '#FFFFFF'), + brightness: Brightness.light, leading: IconButton( icon: Icon( Icons.arrow_back_ios, diff --git a/lib/pages/message_notice_page/message_notice_page.dart b/lib/pages/message_notice_page/message_notice_page.dart index 7a1d242..b007d2e 100644 --- a/lib/pages/message_notice_page/message_notice_page.dart +++ b/lib/pages/message_notice_page/message_notice_page.dart @@ -228,7 +228,7 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine child: Column( children: [ Container( - height: 30, + // height: 30, width: double.infinity, child: Row( children: [ @@ -527,6 +527,7 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine /// APPBar Widget _buildAppBarWidget(MessageNoticeStyleModel styleModel) { return AppBar( + brightness: Brightness.light, leading: IconButton( icon: Icon( Icons.arrow_back_ios, diff --git a/lib/pages/team_details_page/team_details_page.dart b/lib/pages/team_details_page/team_details_page.dart index 75aec76..20a8d8c 100644 --- a/lib/pages/team_details_page/team_details_page.dart +++ b/lib/pages/team_details_page/team_details_page.dart @@ -94,6 +94,7 @@ class _TeamDetailsPageState extends State<_TeamDetailsPage> { /// 头部Bar SliverAppBar( // expandedHeight: 200.0, + brightness: Brightness.light, leading: IconButton( icon: Icon( Icons.arrow_back_ios, diff --git a/lib/widgets/goods_details/detail_img/goods_details_img.dart b/lib/widgets/goods_details/detail_img/goods_details_img.dart index b597396..6a3cff3 100644 --- a/lib/widgets/goods_details/detail_img/goods_details_img.dart +++ b/lib/widgets/goods_details/detail_img/goods_details_img.dart @@ -84,14 +84,19 @@ class _GoodsDetailsImgWidgetContainerState extends State 0) { + return Column( + children: model.image_detail_list.map((item) { + return CachedNetworkImage( + imageUrl: item ?? '', + fit: BoxFit.fitWidth, + ); + }).toList(), + ); + }else{ + return Container(); + } } /// 标题Widget diff --git a/lib/widgets/team/appbar/team_app_bar_widget.dart b/lib/widgets/team/appbar/team_app_bar_widget.dart index aaa5cee..e1e39c4 100644 --- a/lib/widgets/team/appbar/team_app_bar_widget.dart +++ b/lib/widgets/team/appbar/team_app_bar_widget.dart @@ -13,6 +13,7 @@ class TeamAppBarWidget extends StatelessWidget { return SliverAppBar( // expandedHeight: 200.0, + brightness: Brightness.light, leading: IconButton( icon: Icon( Icons.arrow_back_ios, diff --git a/lib/widgets/team/recommend/team_recommend_widget.dart b/lib/widgets/team/recommend/team_recommend_widget.dart index 1fe2dac..65d6a4a 100644 --- a/lib/widgets/team/recommend/team_recommend_widget.dart +++ b/lib/widgets/team/recommend/team_recommend_widget.dart @@ -251,12 +251,15 @@ class __TeamRecommendWidgetState extends State<_TeamRecommendWidgetContainer> { /// 头像widget Widget _getAvatarWidget(TeamDataModel dataModel) { - return Container( - width: 55, - // height: 55, - // color: Colors.red, - child: CachedNetworkImage( - imageUrl: dataModel?.referrerAvatar ?? '', + return ClipRRect( + borderRadius: BorderRadius.circular(55/2), + child: Container( + width: 55, + // height: 55, + // color: Colors.red, + child: CachedNetworkImage( + imageUrl: dataModel?.referrerAvatar ?? '', + ), ), ); } From df31200376bc6f932d81b7a8a97894d48dea16df Mon Sep 17 00:00:00 2001 From: PH2 <1293456824@qq.com> Date: Fri, 30 Oct 2020 14:36:53 +0800 Subject: [PATCH 3/6] =?UTF-8?q?1=E3=80=81=E6=94=B6=E8=97=8F=E5=A4=B9?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=BB=91=E5=8A=A8=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/favorites_page/favorites_page.dart | 1 + .../dialog/favorites_dialog_widget.dart | 2 +- .../bloc/favorites_goods_list_bloc.dart | 15 +++++ .../bloc/favorites_goods_list_event.dart | 6 ++ .../bloc/favorites_goods_list_repository.dart | 32 +++++++--- .../favorites_goods_list_widget.dart | 59 ++++++++++++++++--- pubspec.yaml | 2 + 7 files changed, 101 insertions(+), 16 deletions(-) diff --git a/lib/pages/favorites_page/favorites_page.dart b/lib/pages/favorites_page/favorites_page.dart index d7364a7..e359d94 100644 --- a/lib/pages/favorites_page/favorites_page.dart +++ b/lib/pages/favorites_page/favorites_page.dart @@ -171,6 +171,7 @@ class _FavoritesPageContainerState extends State<_FavoritesPageContainer> with T if (length > 0) { int index = -1; return TabBarView( + physics: NeverScrollableScrollPhysics(), controller: _tabController, children: model.tabList.map((e) { ++index; diff --git a/lib/widgets/favorites/dialog/favorites_dialog_widget.dart b/lib/widgets/favorites/dialog/favorites_dialog_widget.dart index 39ecb24..1790f47 100644 --- a/lib/widgets/favorites/dialog/favorites_dialog_widget.dart +++ b/lib/widgets/favorites/dialog/favorites_dialog_widget.dart @@ -23,7 +23,7 @@ class FavoritesDialogWidget extends StatelessWidget { child: Column( children: [ /// 标题 - Text(styleModel?.bgText, style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: HexColor.fromHex(styleModel?.bgTextColor ?? '#333333'))), + Text(styleModel?.bgText ?? '', style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: HexColor.fromHex(styleModel?.bgTextColor ?? '#333333'))), const SizedBox(height: 44), Row( children: [ diff --git a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart index 4ca4489..871e0aa 100644 --- a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart +++ b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart @@ -60,10 +60,16 @@ class FavoritesGoodsListBloc extends Bloc _mapSlideDeleteEventToState(FavoritesGoodsListSlideDeleteEvent event) async*{ + var result = await repository.slideDeleteData(event.index); + if (!EmptyUtil.isEmpty(result)) { + yield FavoritesGoodsListLoadedState(dataModel: result); + } else { + yield FavoritesGoodsListErrorState(); + } + } // /// 切换样式 diff --git a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart index d687a76..e601921 100644 --- a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart +++ b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart @@ -19,6 +19,12 @@ class FavoritesGoodsListSearchEvent extends FavoritesGoodsListEvent { FavoritesGoodsListSearchEvent(this.keyword); } +/// 右滑动删除 +class FavoritesGoodsListSlideDeleteEvent extends FavoritesGoodsListEvent{ + final int index; + FavoritesGoodsListSlideDeleteEvent(this.index); +} + /// 删除 class FavoritesGoodsListDeleteEvent extends FavoritesGoodsListEvent {} diff --git a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart index 42d3572..e0529d3 100644 --- a/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart +++ b/lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart @@ -22,17 +22,33 @@ class FavoritesGoodsListRepository { return _selectIndex.length; } - /// 选中所有 - Future selectAllData() async { + /// 右滑动删除当个商品 + Future slideDeleteData(int index) async{ _selectIndex.clear(); - int index = 0; _oldData.lists.forEach((element) { - element.isSelect = true; - _selectIndex[index] = index; - ++index; + element.isSelect = false; }); - _oldData.isAllSelect = true; - return _oldData; + _oldData.isAllSelect = false; + _selectIndex[index] = index; + return delete(); + } + + /// 选中所有 + Future selectAllData() async { + try { + _selectIndex.clear(); + int index = 0; + _oldData.lists.forEach((element) { + element.isSelect = true; + _selectIndex[index] = index; + ++index; + }); + _oldData.isAllSelect = true; + return _oldData; + }catch(e, s){ + Logger.error(e,s); + } + return null; } /// 单个选中状态 diff --git a/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart b/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart index 7f3bb6c..1f458ec 100644 --- a/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart +++ b/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart @@ -1,6 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:zhiying_base_widget/dialog/tip_dialog/tip_dialog.dart'; import 'package:zhiying_base_widget/pages/favorites_page/model/favorites_style_model.dart'; @@ -46,6 +47,7 @@ class _FavoritesGoodsListWidgetContainer extends StatefulWidget { class __FavoritesGoodsListWidgetContainerState extends State<_FavoritesGoodsListWidgetContainer> with AutomaticKeepAliveClientMixin { RefreshController _refreshController; + SlidableController _slidableController; // 是否编辑中 bool isEditing = false; @@ -61,6 +63,21 @@ class __FavoritesGoodsListWidgetContainerState extends State<_FavoritesGoodsList BlocProvider.of(context).add(FavoritesGoodsListOnLoadEvent()); } + /// 右边划删除 + void _onSlideDelete(ConfirmDialog styleModel,int index) async{ + var result = await showDialog(context: context, child: FavoritesDialogWidget(styleModel: styleModel,)); + if(result == 1){ + BlocProvider.of(context).add(FavoritesGoodsListSlideDeleteEvent(index)); + // Slidable.of(context)?.renderingMode == SlidableRenderingMode.none ? Slidable.of(context)?.open() : Slidable.of(context)?.close(); + // Slidable.of(context)?.close(); + } + } + + /// 分享商品 + void _onSlideShare() async{ + // TODO 分享商品还没弄 + } + /// 商品点击选中 void _onClickGoods(int index){ BlocProvider.of(context).add(FavoritesGoodsListSignGoodsSelectEvent(index)); @@ -92,6 +109,7 @@ class __FavoritesGoodsListWidgetContainerState extends State<_FavoritesGoodsList @override void initState() { _refreshController = RefreshController(); + _slidableController = SlidableController(); BlocProvider.of(context).add(FavoritesGoodsListInitEvent()); super.initState(); } @@ -214,13 +232,40 @@ class __FavoritesGoodsListWidgetContainerState extends State<_FavoritesGoodsList ), ), Expanded( - child: HomeGoodsItemSingle( - item, - HomeGoodsStyleModel()..listStyle = styleModel?.listStyle, - marginBottom: 0, - marginLeft: 0, - marginRight: 0, - marginTop: 0, + child: Slidable( + key: Key(index.toString()), + controller: _slidableController, + enabled: !isEditing, + actionPane: SlidableDrawerActionPane(), + actionExtentRatio: 0.25, + closeOnScroll: false, + secondaryActions: [ + /// 分享 + IconSlideAction( + caption: '分享', + color: Colors.deepOrange, + icon: Icons.share, + onTap: () => _onSlideShare(), + closeOnTap: true, + ), + + /// 删除 + IconSlideAction( + caption: '删除', + color: Colors.red, + closeOnTap: true, + icon: Icons.delete, + onTap: () => _onSlideDelete(styleModel?.confirmDialog ,index), + ), + ], + child: HomeGoodsItemSingle( + item, + HomeGoodsStyleModel()..listStyle = styleModel?.listStyle, + marginBottom: 8, + marginLeft: 0, + marginRight: 0, + marginTop: 0 + ), ), ) ], diff --git a/pubspec.yaml b/pubspec.yaml index 8a52ad3..5b7f2b8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,6 +31,8 @@ dependencies: flutter_native_image: ^0.0.5 #字符检测 string_validator: 0.1.4 + # 列表滑动删除 + flutter_slidable: 0.5.7 # image_gallery_saver: ^1.6.0 permission_handler: From 0ae811e92c98bd451e1a0040c1ea1cdd4170073c Mon Sep 17 00:00:00 2001 From: PH2 <1293456824@qq.com> Date: Fri, 30 Oct 2020 17:28:13 +0800 Subject: [PATCH 4/6] =?UTF-8?q?1=E3=80=81=E6=B6=88=E6=81=AF=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E7=9A=84=E6=B6=88=E9=99=A4=E7=BA=A2=E7=82=B9=202?= =?UTF-8?q?=E3=80=81=E6=94=B6=E8=97=8F=E5=A4=B9=E7=9A=84=E8=BE=B9=E8=B7=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bloc/message_notice_bloc.dart | 17 +++++++++++ .../bloc/message_notice_event.dart | 14 +++++++-- .../bloc/message_notice_repository.dart | 15 ++++++++++ .../message_notice_page.dart | 12 +++++--- lib/register.dart | 3 ++ .../favorites_goods_list_widget.dart | 30 +++++++++++-------- .../home_quick_entry_widget.dart | 17 ++++++----- .../home_slide_banner/home_slide_banner.dart | 4 +-- 8 files changed, 84 insertions(+), 28 deletions(-) diff --git a/lib/pages/message_notice_page/bloc/message_notice_bloc.dart b/lib/pages/message_notice_page/bloc/message_notice_bloc.dart index 48de94f..0239471 100644 --- a/lib/pages/message_notice_page/bloc/message_notice_bloc.dart +++ b/lib/pages/message_notice_page/bloc/message_notice_bloc.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; +import 'package:flutter/cupertino.dart'; import 'package:zhiying_base_widget/pages/message_notice_page/bloc/message_notice_repository.dart'; import 'package:zhiying_base_widget/pages/message_notice_page/model/message_notice_data_model.dart'; import 'package:zhiying_base_widget/pages/message_notice_page/model/message_notice_style_model.dart'; @@ -31,6 +32,11 @@ class MessageNoticeBloc extends Bloc { yield* _mapInitEventToState(event); } + /// 消除红点 + if (event is MessageNoticeClearPointEvent) { + yield* _mapClearPointEventToState(event); + } + /// 下拉刷新 if (event is MessageNoticeOnRefreshEvent) { yield* _mapOnRefreshEventToState(event); @@ -61,6 +67,17 @@ class MessageNoticeBloc extends Bloc { } } + /// 消除消息右上角红点 + Stream _mapClearPointEventToState(MessageNoticeClearPointEvent event) async* { + var style = repository.getStyleModel(); + var data = await repository.fetchClearPointData(event.selectId); + if (!EmptyUtil.isEmpty(data)) { + yield MessageNoticeLoadedState(styleModel: style, dataModel: data); + }else{ + yield MessageNoticeOnRefreshErrorState(); + } + } + /// 下拉刷新 Stream _mapOnRefreshEventToState(MessageNoticeOnRefreshEvent event) async* { var style = repository.getStyleModel(); diff --git a/lib/pages/message_notice_page/bloc/message_notice_event.dart b/lib/pages/message_notice_page/bloc/message_notice_event.dart index 8ce3d6c..c035544 100644 --- a/lib/pages/message_notice_page/bloc/message_notice_event.dart +++ b/lib/pages/message_notice_page/bloc/message_notice_event.dart @@ -11,7 +11,17 @@ abstract class MessageNoticeEvent extends Equatable { class MessageNoticeInitEvent extends MessageNoticeEvent {} /// 下拉刷新 -class MessageNoticeOnRefreshEvent extends MessageNoticeEvent{} +class MessageNoticeOnRefreshEvent extends MessageNoticeEvent {} /// 上拉更多 -class MessageNoticeOnLoadEvent extends MessageNoticeEvent{} \ No newline at end of file +class MessageNoticeOnLoadEvent extends MessageNoticeEvent {} + +/// 消除消息红点 +class MessageNoticeClearPointEvent extends MessageNoticeEvent { + final String selectId; + + MessageNoticeClearPointEvent({@required this.selectId}); + + @override + List get props => [this.selectId]; +} diff --git a/lib/pages/message_notice_page/bloc/message_notice_repository.dart b/lib/pages/message_notice_page/bloc/message_notice_repository.dart index 105f349..ee653a0 100644 --- a/lib/pages/message_notice_page/bloc/message_notice_repository.dart +++ b/lib/pages/message_notice_page/bloc/message_notice_repository.dart @@ -79,6 +79,21 @@ class MessageNoticeRepository { return null; } + /// 消除消息红点 + Future fetchClearPointData(String selectId) async{ + try{ + _oldData.forEach((element){ + if(element.id == selectId) { + element.unread_count = ''; + } + }); + return MessageNoticeDataModel()..list = _oldData; + }catch(e, s){ + Logger.error(e,s); + } + return null; + } + /// 下拉刷新 Future fetchRefreshData() async { return fetchInitData(); diff --git a/lib/pages/message_notice_page/message_notice_page.dart b/lib/pages/message_notice_page/message_notice_page.dart index b007d2e..aa08af4 100644 --- a/lib/pages/message_notice_page/message_notice_page.dart +++ b/lib/pages/message_notice_page/message_notice_page.dart @@ -51,7 +51,11 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine } /// 子item点击事件 - void _onMainItemClick(MainNotificationStyleItem styleModel) { + void _onMainItemClick(MainNotificationStyleItem styleModel, MessageNoticeDataItemModel dataModel) { + + /// 消除消息红点 + BlocProvider.of(context).add(MessageNoticeClearPointEvent(selectId: dataModel?.id)); + /// 如果是消息中心,则重新打开页面加载 Navigator.push(context, CupertinoPageRoute(builder: (_) => MessageNoticePage({'type': styleModel?.type, 'title': styleModel?.name}))); } @@ -221,7 +225,7 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine return GestureDetector( behavior: HitTestBehavior.opaque, - onTap: () => _onMainItemClick(styleModel), + onTap: () => _onMainItemClick(styleModel, dataModel), child: Container( decoration: BoxDecoration(color: HexColor.fromHex(styleModel?.bg_color ?? '#FFFFFF'), borderRadius: borderRadius), padding: const EdgeInsets.only(left: 15, right: 15, top: 16), @@ -569,7 +573,7 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine offset: Offset(5, -4.5), child: Container( // width: 17, - height: 12, + // height: 12, padding: const EdgeInsets.only(left: 3, right: 3, top: 1, bottom: 1), alignment: Alignment.center, decoration: BoxDecoration( @@ -577,7 +581,7 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine borderRadius: BorderRadius.circular(6), border: Border.all(color: HexColor.fromHex('#FFFFFF'), width: 0.5)), child: Text( - '18', + value?? '', textAlign: TextAlign.center, style: TextStyle(fontSize: 9, color: HexColor.fromHex(unreadTextColor ?? '#FFFFFF')), ), diff --git a/lib/register.dart b/lib/register.dart index 158ad42..49998c6 100644 --- a/lib/register.dart +++ b/lib/register.dart @@ -156,6 +156,9 @@ class BaseWidgetRegister { PageFactory.regist( 'pub.flutter.message_center', (model) => MessageNoticePage(model)); + /// TODO 首页的消息中心标识和我的页面不一致,需要改 + PageFactory.regist( + 'pub.flutter.message', (model) => MessageNoticePage(model)); /// 我的收藏 PageFactory.regist('pub.flutter.my_fav', (model) => FavoritesPage()); } diff --git a/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart b/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart index 1f458ec..8b879a5 100644 --- a/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart +++ b/lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart @@ -241,21 +241,27 @@ class __FavoritesGoodsListWidgetContainerState extends State<_FavoritesGoodsList closeOnScroll: false, secondaryActions: [ /// 分享 - IconSlideAction( - caption: '分享', - color: Colors.deepOrange, - icon: Icons.share, - onTap: () => _onSlideShare(), - closeOnTap: true, + Padding( + padding: const EdgeInsets.only(bottom: 8), + child: IconSlideAction( + caption: '分享', + color: Colors.deepOrange, + icon: Icons.share, + onTap: () => _onSlideShare(), + closeOnTap: true, + ), ), /// 删除 - IconSlideAction( - caption: '删除', - color: Colors.red, - closeOnTap: true, - icon: Icons.delete, - onTap: () => _onSlideDelete(styleModel?.confirmDialog ,index), + Padding( + padding: const EdgeInsets.only(bottom: 8), + child: IconSlideAction( + caption: '删除', + color: Colors.red, + closeOnTap: true, + icon: Icons.delete, + onTap: () => _onSlideDelete(styleModel?.confirmDialog ,index), + ), ), ], child: HomeGoodsItemSingle( diff --git a/lib/widgets/home/home_quick_entry/home_quick_entry_widget.dart b/lib/widgets/home/home_quick_entry/home_quick_entry_widget.dart index b091790..e474c04 100644 --- a/lib/widgets/home/home_quick_entry/home_quick_entry_widget.dart +++ b/lib/widgets/home/home_quick_entry/home_quick_entry_widget.dart @@ -59,10 +59,11 @@ class _HomeQuickEntryWidgetContianerState ); } + /// 主视图 Widget _getMainWidget(HomeQuickEntryModel model) { - int dataSize = 15; //model?.type_normal?.length ?? 0; // 总数 - int columSize = 5; //int.parse(model?.colum_size ?? '5'); // 列数 - int rowSize = 2; //int.parse(model?.row_size ?? '2'); // 行数 + int dataSize = model?.type_normal?.length ?? 0; // 总数 + int columSize = int.parse(model?.colum_size ?? '5'); // 列数 + int rowSize = int.parse(model?.row_size ?? '2'); // 行数 rowSize = columSize * rowSize <= dataSize ? rowSize : dataSize % columSize == 0 @@ -84,9 +85,9 @@ class _HomeQuickEntryWidgetContianerState const double titleHeight = 20; // 总体的高度 == 行数 * (图片高度 + 标题高度 + 元素之间的边距) + 上下内边距 - double containerHeight = - rowSize * (iconHeight + titleHeight + itemPadding * 2) + - (bottomSize * 2); + double containerHeight = rowSize * (iconHeight + titleHeight + itemPadding * 2) + (bottomSize * 2); + + return Container( // padding: const EdgeInsets.only(bottom: bottomSize, top: bottomSize), @@ -121,7 +122,7 @@ class _HomeQuickEntryWidgetContianerState itemPadding: itemPadding, ); }, - pagination: _SwiperCustomPagination(pageCount), + pagination: pageCount > 1 ? _SwiperCustomPagination(pageCount) : null, ), ), ) @@ -130,7 +131,7 @@ class _HomeQuickEntryWidgetContianerState ); } - // 自定义进度条 + /// 自定义进度条 SwiperPlugin _SwiperCustomPagination(int pageCount) { List list = []; for (int i = 0; i < pageCount; i++) { diff --git a/lib/widgets/home/home_slide_banner/home_slide_banner.dart b/lib/widgets/home/home_slide_banner/home_slide_banner.dart index 755b90b..570676a 100644 --- a/lib/widgets/home/home_slide_banner/home_slide_banner.dart +++ b/lib/widgets/home/home_slide_banner/home_slide_banner.dart @@ -7,6 +7,7 @@ import 'package:provider/provider.dart'; import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart'; import 'package:zhiying_base_widget/pages/message_notice_page/message_notice_page.dart'; import 'package:zhiying_base_widget/pages/team_details_page/team_details_page.dart'; +import 'package:zhiying_base_widget/pages/vip_center_page/vip_center_page.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; import 'bloc/bloc.dart'; @@ -54,8 +55,7 @@ class _HomeSlideBannerContainerState extends State { // )); // Navigator.push(context, CupertinoPageRoute(builder: (_)=> TeamPage())); - Navigator.push( - context, CupertinoPageRoute(builder: (_) => MessageNoticePage(null))); + // Navigator.push(context, CupertinoPageRoute(builder: (_) => VipCenterPage(null))); } @override From 1d53b9ebad3a6199c2b7dff480cf07f94ee3882b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=8D=8E=E8=BD=A9?= <646903573@qq.com> Date: Mon, 2 Nov 2020 18:09:52 +0800 Subject: [PATCH 5/6] =?UTF-8?q?1.=E6=B7=BB=E5=8A=A0=E9=92=B1=E5=8C=85?= =?UTF-8?q?=E6=98=8E=E7=BB=86=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bil_detail_page/bil_detail_page.dart | 212 +--- .../bil_detail_page/bil_detail_page_bloc.dart | 5 +- lib/pages/home_page/home_page.dart | 1 + lib/register.dart | 14 +- .../home_slide_banner/home_slide_banner.dart | 1 - lib/widgets/wallet/wallet_bil/wallet_bil.dart | 9 +- .../model/wallet_style_model.dart | 287 ++++++ .../wallet_bil_detail/wallet_bil_detail.dart | 918 ++++++++++++++++++ .../wallet_bil_detail_widget_bloc.dart | 163 ++++ .../wallet_bil_detail/wallet_list_widget.dart | 606 ++++++++++++ 10 files changed, 2020 insertions(+), 196 deletions(-) create mode 100644 lib/widgets/wallet_bil_detail/model/wallet_style_model.dart create mode 100644 lib/widgets/wallet_bil_detail/wallet_bil_detail.dart create mode 100644 lib/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart create mode 100644 lib/widgets/wallet_bil_detail/wallet_list_widget.dart diff --git a/lib/pages/bil_detail_page/bil_detail_page.dart b/lib/pages/bil_detail_page/bil_detail_page.dart index e7fb191..4da82d7 100644 --- a/lib/pages/bil_detail_page/bil_detail_page.dart +++ b/lib/pages/bil_detail_page/bil_detail_page.dart @@ -16,6 +16,7 @@ import 'package:zhiying_comm/util/custom_sliver_persistent_header_delegate.dart' import 'package:zhiying_comm/zhiying_comm.dart'; import 'package:flutter_alibc/flutter_alibc.dart'; +///钱包明细 class BilDetailPage extends StatefulWidget { final Map data; @@ -61,206 +62,45 @@ class _BilDetailPageContainerState extends State { @override void initState() { _bloc = BlocProvider.of(context); + _bloc.loadData(widget.data[Constants.SkipIdentifierName]); showDate = DateFormat('yyyy-MM').format(DateTime.now()); super.initState(); } @override Widget build(BuildContext context) { - return StreamBuilder( + stream: _bloc.outData, builder: (context, sny) { + if (sny.data == null) { + return Container(); + } + var model = sny.data; return Scaffold( - appBar: AppBar( - centerTitle: true, - title: Text("明细"), - ), body: Container( - child: ListView( - shrinkWrap: true, - children: [_buildType(), _buildBottomItem()], - ), - ), + child: Column( + children: _buildItem(model), + )), ); }, ); } - _buildType() { - return Row( - children: [ - SizedBox(width: 12.5), - InkWell( - onTap: () { - ///显示日期选择弹窗 - _selectDate(); - }, - child: Padding( - padding: const EdgeInsets.only(top: 8, bottom: 8), - child: Text(showDate ?? ""), - ), - ), - Icon(Icons.arrow_drop_down), - Expanded( - child: Container( - height: 50, - child: ListView.builder( - scrollDirection: Axis.horizontal, - shrinkWrap: true, - itemCount: 3, - itemBuilder: (context, index) { - return InkWell(child: Container( - margin: - EdgeInsets.only(top: 10, left: 8, right: 8, bottom: 10), - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(50)), - child: Padding( - padding: const EdgeInsets.only(left: 16, right: 16), - child: Center( - child: Text( - "推广", - style: TextStyle(color: Colors.grey), - )), - ), - ),onTap: () async { - print("ok"); - await FlutterAlibc.loginTaoBao(); - },); - }), - )) - ], - ); - } - - void _selectDate() async { - showDialog(context: context, builder: (context) => SelectDateYMDialog()); - } - - _buildBottomItem() { - return ListView.builder( - shrinkWrap: true, itemCount: 10, itemBuilder: _buildItem); - } - - Widget _buildItem(BuildContext context, int index) { - return Container( - margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), - padding: - EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4), - color: Colors.red[100], - border: Border.all(color: Colors.red)), - child: Padding( - padding: const EdgeInsets.only( - left: 4, right: 4, top: 2, bottom: 2), - child: Center( - child: Text( - "自购", - style: TextStyle(color: Colors.red, fontSize: 20.sp), - ), - ), - ), - ), - Container( - width: 443.w, - margin: EdgeInsets.only(left: 15.w), - child: Text( - "Segway Ninebot mini Pro智能代的卅饭店发生的范德萨地方撒发生", - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle(fontSize: 28.sp), - )) - ], - ), - Row( - children: [ - Text( - "+", - style: TextStyle(color: Colors.red), - ), - Text( - "¥8.00", - style: TextStyle(color: Colors.red, fontSize: 30.sp), - ) - ], - ) - ], - ), - SizedBox( - height: 4, - ), - Row( - children: [ - Text( - "订单编号:", - style: TextStyle( - color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), - ), - Text( - "1233333333", - style: TextStyle( - color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), - ), - SizedBox( - width: 28.w, - ), - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4), - color: HexColor.fromHex("#FFF5F5F5"), - border: Border.all(color: HexColor.fromHex("#FFD6D6D6"))), - child: Padding( - padding: - EdgeInsets.only(left: 16, right: 16, top: 1, bottom: 1), - child: Text( - "复制", - style: TextStyle( - color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), - ), - ), - ) - ], - ), - Row( - children: [ - Text( - "订单编号:", - style: TextStyle( - color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), - ), - Text( - "1233333333", - style: TextStyle( - color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), - ), - ], - ), - Row( - children: [ - Text( - "订单编号:", - style: TextStyle( - color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), - ), - Text( - "1233333333", - style: TextStyle( - color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), - ), - - ], - ) - ], - ), - ); + ///构建子模块 + _buildItem(List> model) { + List list = List(); + for (var item in model) { + WidgetModel widgetModel = + WidgetModel.fromJson(Map.from(item)); + if (widgetModel.modName == 'my_wallet_detail') { + list.add(Expanded( + child: WidgetFactory.create(widgetModel.modName, + isSliver: false, model: item)[0])); + continue; + } + list.addAll(WidgetFactory.create(widgetModel.modName, + isSliver: false, model: item)); + } + return list; } } diff --git a/lib/pages/bil_detail_page/bil_detail_page_bloc.dart b/lib/pages/bil_detail_page/bil_detail_page_bloc.dart index 9623a0e..d856976 100644 --- a/lib/pages/bil_detail_page/bil_detail_page_bloc.dart +++ b/lib/pages/bil_detail_page/bil_detail_page_bloc.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:zhiying_base_widget/widgets/wallet_bil_detail/model/wallet_style_model.dart'; import 'package:zhiying_comm/util/base_bloc.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; @@ -11,7 +12,7 @@ class BilDetailPageBloc extends BlocBase { Stream>> get outData => _tabController.stream; - + BilDetailStyleModel bilDetailStyleModel; @override void dispose() { @@ -21,7 +22,7 @@ class BilDetailPageBloc extends BlocBase { loadData(String skipIdentifier) { - NetUtil.request('/api/v1/mod/${skipIdentifier}', method: NetMethod.GET, + NetUtil.request('/api/v1/mod/pub.flutter.my_wallet_detail', method: NetMethod.GET, onCache: (data) { _loadData(data); }, onSuccess: (data) { diff --git a/lib/pages/home_page/home_page.dart b/lib/pages/home_page/home_page.dart index d4355a0..7c1094d 100644 --- a/lib/pages/home_page/home_page.dart +++ b/lib/pages/home_page/home_page.dart @@ -72,6 +72,7 @@ class _HomePageState extends State { String selectedIcon = ImageUtil.getUrl(model.chooseIcon ?? model.icon); String textColor = model.fontColor; String chooseColor = model.chooseColor ?? textColor; + items.add(BottomNavigationBarItem( icon: Container( width: 24, diff --git a/lib/register.dart b/lib/register.dart index 49998c6..1bf7a20 100644 --- a/lib/register.dart +++ b/lib/register.dart @@ -1,6 +1,6 @@ import 'package:sharesdk_plugin/sharesdk_interface.dart'; import 'package:sharesdk_plugin/sharesdk_register.dart'; - +import 'package:zhiying_base_widget/pages/bil_detail_page/bil_detail_page.dart'; import 'package:zhiying_base_widget/pages/feedback_page/feedback_page.dart'; import 'package:zhiying_base_widget/pages/goods_details_page/goods_details_page.dart'; import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; @@ -49,6 +49,7 @@ import 'package:zhiying_base_widget/widgets/wallet/wallet_bil/wallet_bil.dart'; 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_base_widget/widgets/wallet_bil_detail/wallet_bil_detail.dart'; import 'package:zhiying_comm/util/defalut_widget_creater.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; @@ -155,12 +156,18 @@ class BaseWidgetRegister { /// 消息中心 PageFactory.regist( 'pub.flutter.message_center', (model) => MessageNoticePage(model)); + PageFactory.regist( + 'pub.flutter.message_notice', (model) => MessageNoticePage(model)); /// TODO 首页的消息中心标识和我的页面不一致,需要改 PageFactory.regist( 'pub.flutter.message', (model) => MessageNoticePage(model)); /// 我的收藏 PageFactory.regist('pub.flutter.my_fav', (model) => FavoritesPage()); + + + ///钱包明细 + PageFactory.regist('pub.flutter.my_bil', (model) => BilDetailPage(model)); } // 注册控件 @@ -327,6 +334,11 @@ class BaseWidgetRegister { 'wallet_income', DefaultWidgetCreater((model) => WalletIncome())); //======================= 账单明细 + WidgetFactory.regist( + 'my_wallet_detail', + DefaultWidgetCreater((model) => WalletBilDetail( + data: model, + ))); //======================== 热榜 WidgetFactory.regist('hot_rank_appbar', diff --git a/lib/widgets/home/home_slide_banner/home_slide_banner.dart b/lib/widgets/home/home_slide_banner/home_slide_banner.dart index 570676a..132583c 100644 --- a/lib/widgets/home/home_slide_banner/home_slide_banner.dart +++ b/lib/widgets/home/home_slide_banner/home_slide_banner.dart @@ -7,7 +7,6 @@ import 'package:provider/provider.dart'; import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart'; import 'package:zhiying_base_widget/pages/message_notice_page/message_notice_page.dart'; import 'package:zhiying_base_widget/pages/team_details_page/team_details_page.dart'; -import 'package:zhiying_base_widget/pages/vip_center_page/vip_center_page.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; import 'bloc/bloc.dart'; diff --git a/lib/widgets/wallet/wallet_bil/wallet_bil.dart b/lib/widgets/wallet/wallet_bil/wallet_bil.dart index 430343a..e6adecb 100644 --- a/lib/widgets/wallet/wallet_bil/wallet_bil.dart +++ b/lib/widgets/wallet/wallet_bil/wallet_bil.dart @@ -3,6 +3,7 @@ import 'dart: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/pages/bil_detail_page/bil_detail_page.dart'; import 'package:zhiying_base_widget/pages/wallet_page/wallet_detail_page.dart'; import 'package:zhiying_base_widget/widgets/wallet/wallet_bil/model/wallet_bli_model.dart'; import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income_sk.dart'; @@ -24,12 +25,8 @@ class WalletBil extends StatelessWidget { ? WalletIncomeSkeleton() : GestureDetector( onTap: () { - Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => WalletDetailPage(), - ), - ); + RouterUtil.route( + SkipModel.fromJson(json.decode(data['data'])), data, context); }, child: Container( decoration: BoxDecoration( diff --git a/lib/widgets/wallet_bil_detail/model/wallet_style_model.dart b/lib/widgets/wallet_bil_detail/model/wallet_style_model.dart new file mode 100644 index 0000000..0dc80b2 --- /dev/null +++ b/lib/widgets/wallet_bil_detail/model/wallet_style_model.dart @@ -0,0 +1,287 @@ +class BilDetailStyleModel { + String appBarName; + String appBarNameColor; + String appBarBgImg; + String appBarBgColor; + String tabLineColor; + String tabNoSeletedColor; + String tabSeletedColor; + List tabList; + String timeSelectColor; + String btnNoSelectedColor; + String btnSelectedColor; + List inputTabViewBtns; + List outTabViewBtns; + InputItemStyle inputItemStyle; + OutputItemStyle outputItemStyle; + + BilDetailStyleModel( + {this.appBarName, + this.appBarNameColor, + this.appBarBgImg, + this.appBarBgColor, + this.tabLineColor, + this.tabNoSeletedColor, + this.tabSeletedColor, + this.tabList, + this.timeSelectColor, + this.btnNoSelectedColor, + this.btnSelectedColor, + this.inputTabViewBtns, + this.outTabViewBtns, + this.inputItemStyle, + this.outputItemStyle}); + + BilDetailStyleModel.fromJson(Map json) { + appBarName = json['app_bar_name']; + appBarNameColor = json['app_bar_name_color']; + appBarBgImg = json['app_bar_bg_img']; + appBarBgColor = json['app_bar_bg_color']; + tabLineColor = json['tab_line_color']; + tabNoSeletedColor = json['tab_no_seleted_color']; + tabSeletedColor = json['tab_seleted_color']; + if (json['tab_list'] != null) { + tabList = new List(); + json['tab_list'].forEach((v) { + tabList.add(new TabList.fromJson(v)); + }); + } + timeSelectColor = json['time_select_color']; + btnNoSelectedColor = json['btn_no_selected_color']; + btnSelectedColor = json['btn_selected_color']; + if (json['input_tab_view_btns'] != null) { + inputTabViewBtns = new List(); + json['input_tab_view_btns'].forEach((v) { + inputTabViewBtns.add(new InputTabViewBtns.fromJson(v)); + }); + } + if (json['out_tab_view_btns'] != null) { + outTabViewBtns = new List(); + json['out_tab_view_btns'].forEach((v) { + outTabViewBtns.add(new InputTabViewBtns.fromJson(v)); + }); + } + inputItemStyle = json['input_item_style'] != null + ? new InputItemStyle.fromJson(json['input_item_style']) + : null; + outputItemStyle = json['output_item_style'] != null + ? new OutputItemStyle.fromJson(json['output_item_style']) + : null; + } + + Map toJson() { + final Map data = new Map(); + 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['tab_line_color'] = this.tabLineColor; + data['tab_no_seleted_color'] = this.tabNoSeletedColor; + data['tab_seleted_color'] = this.tabSeletedColor; + if (this.tabList != null) { + data['tab_list'] = this.tabList.map((v) => v.toJson()).toList(); + } + data['time_select_color'] = this.timeSelectColor; + data['btn_no_selected_color'] = this.btnNoSelectedColor; + data['btn_selected_color'] = this.btnSelectedColor; + if (this.inputTabViewBtns != null) { + data['input_tab_view_btns'] = + this.inputTabViewBtns.map((v) => v.toJson()).toList(); + } + if (this.outTabViewBtns != null) { + data['out_tab_view_btns'] = + this.outTabViewBtns.map((v) => v.toJson()).toList(); + } + if (this.inputItemStyle != null) { + data['input_item_style'] = this.inputItemStyle.toJson(); + } + if (this.outputItemStyle != null) { + data['output_item_style'] = this.outputItemStyle.toJson(); + } + return data; + } +} + +class TabList { + String type; + String name; + + TabList({this.type, this.name}); + + TabList.fromJson(Map json) { + type = json['type']; + name = json['name']; + } + + Map toJson() { + final Map data = new Map(); + data['type'] = this.type; + data['name'] = this.name; + return data; + } +} + +class InputItemStyle { + String typeNameColor; + String titleColor; + String amountColor; + String contentColor; + String copyBtnText; + String copyBtnTextColor; + String copyBtnBgColor; + String orderIdText; + String orderTypeText; + String amountText; + String timeText; + String settleTimeText; + List keys; + + InputItemStyle( + {this.typeNameColor, + this.titleColor, + this.amountColor, + this.contentColor, + this.copyBtnText, + this.copyBtnTextColor, + this.copyBtnBgColor, + this.orderIdText, + this.orderTypeText, + this.amountText, + this.timeText, + this.settleTimeText, + this.keys}); + + InputItemStyle.fromJson(Map json) { + typeNameColor = json['type_name_color']; + titleColor = json['title_color']; + amountColor = json['amount_color']; + contentColor = json['content_color']; + copyBtnText = json['copy_btn_text']; + copyBtnTextColor = json['copy_btn_text_color']; + copyBtnBgColor = json['copy_btn_bg_color']; + orderIdText = json['order_id_text']; + orderTypeText = json['order_type_text']; + amountText = json['amount_text']; + timeText = json['time_text']; + settleTimeText = json['settle_time_text']; + keys = json['keys'].cast(); + } + + Map toJson() { + final Map data = new Map(); + data['type_name_color'] = this.typeNameColor; + data['title_color'] = this.titleColor; + data['amount_color'] = this.amountColor; + data['content_color'] = this.contentColor; + data['copy_btn_text'] = this.copyBtnText; + data['copy_btn_text_color'] = this.copyBtnTextColor; + data['copy_btn_bg_color'] = this.copyBtnBgColor; + data['order_id_text'] = this.orderIdText; + data['order_type_text'] = this.orderTypeText; + data['amount_text'] = this.amountText; + data['time_text'] = this.timeText; + data['settle_time_text'] = this.settleTimeText; + data['keys'] = this.keys; + return data; + } +} + +class OutputItemStyle { + String typeNameColor; + String titleColor; + String amountColor; + String contentColor; + String copyBtnTextColor; + String copyBtnText; + String copyBtnBgColor; + String orderIdText; + String withdrawAccountText; + String withdrawAmountText; + String withdrawTimeText; + String withdrawOrderStatusText; + String consumeOrderTypeText; + String consumeAmountText; + String consumeTimeText; + List withdrawKeys; + List consumeKeys; + + OutputItemStyle( + {this.typeNameColor, + this.titleColor, + this.amountColor, + this.contentColor, + this.copyBtnTextColor, + this.copyBtnBgColor, + this.orderIdText, + this.withdrawAccountText, + this.withdrawAmountText, + this.withdrawTimeText, + this.withdrawOrderStatusText, + this.consumeOrderTypeText, + this.consumeAmountText, + this.consumeTimeText, + this.withdrawKeys, + this.consumeKeys}); + + OutputItemStyle.fromJson(Map json) { + typeNameColor = json['type_name_color']; + titleColor = json['title_color']; + amountColor = json['amount_color']; + contentColor = json['content_color']; + copyBtnTextColor = json['copy_btn_text_color']; + copyBtnText=json['copy_btn_text']; + copyBtnBgColor = json['copy_btn_bg_color']; + orderIdText = json['order_id_text']; + withdrawAccountText = json['withdraw_account_text']; + withdrawAmountText = json['withdraw_amount_text']; + withdrawTimeText = json['withdraw_time_text']; + withdrawOrderStatusText = json['withdraw_order_status_text']; + consumeOrderTypeText = json['consume_order_type_text']; + consumeAmountText = json['consume_amount_text']; + consumeTimeText = json['consume_time_text']; + withdrawKeys = json['withdraw_keys'].cast(); + consumeKeys = json['consume_keys'].cast(); + } + + Map toJson() { + final Map data = new Map(); + data['type_name_color'] = this.typeNameColor; + data['title_color'] = this.titleColor; + data['amount_color'] = this.amountColor; + data['content_color'] = this.contentColor; + data['copy_btn_text_color'] = this.copyBtnTextColor; + data['copy_btn_bg_color'] = this.copyBtnBgColor; + data['order_id_text'] = this.orderIdText; + data['withdraw_account_text'] = this.withdrawAccountText; + data['withdraw_amount_text'] = this.withdrawAmountText; + data['withdraw_time_text'] = this.withdrawTimeText; + data['withdraw_order_status_text'] = this.withdrawOrderStatusText; + data['consume_order_type_text'] = this.consumeOrderTypeText; + data['consume_amount_text'] = this.consumeAmountText; + data['consume_time_text'] = this.consumeTimeText; + data['withdraw_keys'] = this.withdrawKeys; + data['consume_keys'] = this.consumeKeys; + return data; + } +} + +class InputTabViewBtns { + String type; + String name; + + + InputTabViewBtns( + {this.type,this.name}); + + InputTabViewBtns.fromJson(Map json) { + type=json['type']; + name=json['name']; + } + + Map toJson() { + final Map data = new Map(); + data['name']=name; + data['type']=type; + return data; + } +} \ No newline at end of file diff --git a/lib/widgets/wallet_bil_detail/wallet_bil_detail.dart b/lib/widgets/wallet_bil_detail/wallet_bil_detail.dart new file mode 100644 index 0000000..49babe7 --- /dev/null +++ b/lib/widgets/wallet_bil_detail/wallet_bil_detail.dart @@ -0,0 +1,918 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:intl/intl.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; +import 'package:zhiying_base_widget/dialog/select_date_ym_dialog/select_date_ym_dialog.dart'; +import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_bloc.dart'; +import 'package:zhiying_base_widget/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart'; +import 'package:zhiying_comm/util/base_bloc.dart'; +import 'package:zhiying_comm/util/extension/color.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +import 'model/wallet_style_model.dart'; +import 'package:fluttertoast/fluttertoast.dart'; + +////钱包明细页面 +class WalletBilDetail extends StatefulWidget { + final Map data; + + const WalletBilDetail({Key key, this.data}) : super(key: key); + + @override + _WalletBilDetailState createState() => _WalletBilDetailState(); +} + +class _WalletBilDetailState extends State + with TickerProviderStateMixin, AutomaticKeepAliveClientMixin { + WalletBilDetailWidgetBloc _bloc; + + TabController _tabController; + + @override + void initState() { + _bloc = WalletBilDetailWidgetBloc(); + _bloc.initStyleData(json.decode(widget.data['data'])); + _tabController = + TabController(length: _bloc.styleData.tabList.length, vsync: this); + _bloc.loadInputData(_bloc.inPutCurrentPage, _bloc.inputShowDate); + _bloc.loadOutputData(_bloc.outPutCurrentPage, _bloc.outputShowDate); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return BlocProvider( + bloc: _bloc, + child: Container( + child: Column( + children: [ + AppBar( + brightness: Brightness.light, + backgroundColor: + HexColor.fromHex(_bloc.styleData.appBarBgColor), + centerTitle: true, + leading: IconButton( + icon: Icon( + Icons.arrow_back_ios, + size: 18, + color: HexColor.fromHex(_bloc.styleData.appBarNameColor), + ), + onPressed: () { + Navigator.pop(context); + }), + title: Text( + _bloc.styleData.appBarName ?? "", + style: TextStyle( + color: HexColor.fromHex(_bloc.styleData.appBarNameColor)), + ), + ), + Container( + color: Colors.white, + child: TabBar( + controller: _tabController, + tabs: _buildTabBarItem(), + indicatorWeight: 3, + labelStyle: TextStyle(fontSize: 30.sp), + labelColor: HexColor.fromHex(_bloc.styleData.tabSeletedColor), + unselectedLabelColor: + HexColor.fromHex(_bloc.styleData.tabNoSeletedColor), + indicatorColor: + HexColor.fromHex(_bloc.styleData.tabLineColor), + indicatorSize: TabBarIndicatorSize.label, + ), + ), + Expanded( + child: TabBarView( + controller: _tabController, + children: _buildTabViewPage())) + ], + ), + )); + } + + ///创建tabbar按键 + _buildTabBarItem() { + List listWidget = List(); + for (var item in _bloc.styleData.tabList) { + listWidget.add(Tab( + text: item.name ?? "", + )); + } + return listWidget; + } + + _buildType(List tabViewBtns, TabList tabList) { + var selectType; + if (tabList.type == 'input') { + selectType = _bloc.inputSelectType; + } else { + selectType = _bloc.outputSelectType; + ; + } + return Row( + children: [ + SizedBox(width: 12.5), + InkWell( + onTap: () { + ///显示日期选择弹窗 + _selectDate(tabList); + }, + child: Padding( + padding: const EdgeInsets.only(top: 8, bottom: 8), + child: Text( + tabList.type == "input" + ? _bloc.inputShowDate + : _bloc.outputShowDate, + style: TextStyle( + fontSize: 28.sp, + color: + HexColor.fromHex(_bloc.styleData.timeSelectColor)))), + ), + Icon( + Icons.arrow_drop_down, + color: HexColor.fromHex(_bloc.styleData.timeSelectColor), + ), + Expanded( + child: Container( + height: 50, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: tabViewBtns.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () async { + if (tabList.type == 'input') { + _bloc.inputSelectType = tabViewBtns[index].type; + _bloc.inPutCurrentPage=1; + _bloc.loadInputData( + _bloc.inPutCurrentPage, _bloc.inputShowDate, + type: _bloc.inputSelectType); + } else { + _bloc.outputSelectType = tabViewBtns[index].type; + _bloc.outPutCurrentPage=1; + _bloc.loadOutputData( + _bloc.outPutCurrentPage, _bloc.outputShowDate, + type: _bloc.outputSelectType); + } + _bloc.refresh(); + }, + child: Container( + margin: EdgeInsets.only( + top: 10, left: 8, right: 8, bottom: 10), + decoration: BoxDecoration( + border: Border.all( + color: HexColor.fromHex( + selectType == tabViewBtns[index].type + ? _bloc.styleData.btnSelectedColor + : _bloc.styleData.btnNoSelectedColor), + ), + borderRadius: BorderRadius.circular(50)), + child: Padding( + padding: EdgeInsets.only(left: 16, right: 16), + child: Center( + child: Text( + tabViewBtns[index].name ?? "", + style: TextStyle( + color: HexColor.fromHex( + selectType == tabViewBtns[index].type + ? _bloc.styleData.btnSelectedColor + : _bloc.styleData.btnNoSelectedColor)), + )), + ), + )); + }), + )) + ], + ); + } + + _selectDate(TabList tabList) async { + var result = await showDialog( + context: context, builder: (context) => SelectDateYMDialog()); + if (result != null) { + var dataTime = DateFormat('yyyy-MM').format( + DateTime(int.parse(result['year']), int.parse(result['month']))); + if (tabList.type == "input") { + _bloc.inputShowDate = dataTime; + _bloc.loadInputData(_bloc.inPutCurrentPage, _bloc.inputShowDate); + } else { + _bloc.outputShowDate = dataTime; + _bloc.loadOutputData(_bloc.outPutCurrentPage, _bloc.outputShowDate); + } + _bloc.refresh(); + } + } + + _buildBottomItem(TabList tabList) { + return ListView.builder( + shrinkWrap: true, + itemCount: tabList.type == 'input' + ? _bloc.inputDataVM.length + : _bloc.outputDataVM.length, + itemBuilder: (context, index) { + return _buildItem(context, index, tabList); + }); + } + + Widget _buildItem(BuildContext context, int index, TabList tabList) { + if (tabList.type == 'input') { + InputItemStyle inputItemStyle = _bloc.styleData.inputItemStyle; + var modelItem = _bloc.inputDataVM[index]; + return Container( + margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), + padding: + EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), + decoration: BoxDecoration( + color: HexColor.fromHex("#FFFFFF"), + borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex("#FFFFF3F3"), + border: Border.all( + color: HexColor.fromHex( + inputItemStyle.typeNameColor))), + child: Padding( + padding: const EdgeInsets.only( + left: 4, right: 4, top: 2, bottom: 2), + child: Center( + child: Text( + modelItem['type'] ?? "", + style: TextStyle( + color: HexColor.fromHex( + inputItemStyle.typeNameColor), + fontSize: 20.sp), + ), + ), + ), + ), + Container( + width: 353.w, + margin: EdgeInsets.only(left: 15.w), + child: Text( + modelItem['title'] ?? "", + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 28.sp), + )) + ], + ), + Row( + children: [ + Text( + "+ ", + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.amountColor)), + ), + Text( + "¥ " + modelItem['amount'], + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.amountColor), + fontSize: 30.sp), + ) + ], + ) + ], + ), + SizedBox( + height: 4, + ), + + ///订单编号 + Row( + children: [ + Text( + inputItemStyle.orderIdText, + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['order_id'], + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 28.w, + ), + GestureDetector( + onTap: () { + Clipboard.setData( + ClipboardData(text: modelItem['order_id'])); + Fluttertoast.showToast(msg: "已复制"); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex(inputItemStyle.copyBtnBgColor), + border: Border.all( + color: + HexColor.fromHex(inputItemStyle.contentColor))), + child: Padding( + padding: EdgeInsets.only( + left: 16, right: 16, top: 1, bottom: 1), + child: Text( + inputItemStyle.copyBtnText, + style: TextStyle( + color: + HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + ), + ), + ) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.orderTypeText, + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['order_type'] ?? "", + style: TextStyle( + color: HexColor.fromHex("#FF999999"), + fontSize: 22.sp), + ), + ], + )), + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.amountText + " ¥" + modelItem['amount'], + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + ], + )) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.timeText, + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['time'] ?? "", + style: TextStyle( + color: HexColor.fromHex("#FF999999"), + fontSize: 22.sp), + ), + ], + )), + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.settleTimeText + + " " + + modelItem['settle_time'] ?? + "", + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + ], + )) + ], + ), + ], + ), + ); + } else if (tabList.type == 'output') { + OutputItemStyle outputItemStyle = _bloc.styleData.outputItemStyle; + var modelItem = _bloc.outputDataVM[index]; + if (modelItem['type'] == '消费') { + ///消费返回的Item + return Container( + margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), + padding: + EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), + decoration: BoxDecoration( + color: HexColor.fromHex("#FFFFFF"), + borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex("#FFFFF3F3"), + border: Border.all( + color: HexColor.fromHex( + outputItemStyle.typeNameColor))), + child: Padding( + padding: const EdgeInsets.only( + left: 4, right: 4, top: 2, bottom: 2), + child: Center( + child: Text( + modelItem['type'] ?? "", + style: TextStyle( + color: HexColor.fromHex( + outputItemStyle.typeNameColor), + fontSize: 20.sp), + ), + ), + ), + ), + Container( + width: 353.w, + margin: EdgeInsets.only(left: 15.w), + child: Text( + modelItem['title'] ?? "", + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 28.sp), + )) + ], + ), + Row( + children: [ + Text( + "- ", + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.amountColor)), + ), + Text( + "¥ " + modelItem['amount'], + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.amountColor), + fontSize: 30.sp), + ) + ], + ) + ], + ), + SizedBox( + height: 4, + ), + + ///订单编号 + Row( + children: [ + Text( + outputItemStyle.orderIdText, + style: TextStyle( + color: HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['order_id'], + style: TextStyle( + color: HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 28.w, + ), + GestureDetector( + onTap: () { + Clipboard.setData( + ClipboardData(text: modelItem['order_id'])); + Fluttertoast.showToast(msg: "已复制"); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex(outputItemStyle.copyBtnBgColor), + border: Border.all( + color: HexColor.fromHex( + outputItemStyle.contentColor))), + child: Padding( + padding: EdgeInsets.only( + left: 16, right: 16, top: 1, bottom: 1), + child: Text( + outputItemStyle.copyBtnText ?? "", + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + ), + ), + ) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + outputItemStyle.consumeOrderTypeText, + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['order_type'] ?? "", + style: TextStyle( + color: HexColor.fromHex("#FF999999"), + fontSize: 22.sp), + ), + ], + )), + Expanded( + child: Row( + children: [ + Text( + outputItemStyle.consumeAmountText + + " ¥" + + modelItem['amount'], + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + ], + )) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + outputItemStyle.consumeTimeText, + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['time'] ?? "", + style: TextStyle( + color: HexColor.fromHex("#FF999999"), + fontSize: 22.sp), + ), + ], + )), + // Expanded( + // child: Row( + // children: [ + // Text( + // inputItemStyle.consumeTimeText + + // " " + + // modelItem['settle_time'] ?? + // "", + // style: TextStyle( + // color: HexColor.fromHex(inputItemStyle.contentColor), + // fontSize: 22.sp), + // ), + // ], + // )) + ], + ), + ], + ), + ); + } else if (modelItem['type'] == '提现') { + return Container( + margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), + padding: + EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), + decoration: BoxDecoration( + color: HexColor.fromHex("#FFFFFF"), + borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex("#FFFFF3F3"), + border: Border.all( + color: HexColor.fromHex( + outputItemStyle.typeNameColor))), + child: Padding( + padding: const EdgeInsets.only( + left: 4, right: 4, top: 2, bottom: 2), + child: Center( + child: Text( + modelItem['type'] ?? "", + style: TextStyle( + color: HexColor.fromHex( + outputItemStyle.typeNameColor), + fontSize: 20.sp), + ), + ), + ), + ), + Container( + width: 353.w, + margin: EdgeInsets.only(left: 15.w), + child: Text( + modelItem['title'] ?? "", + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 28.sp), + )) + ], + ), + Row( + children: [ + Text( + "- ", + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.amountColor)), + ), + Text( + "¥ " + modelItem['amount'], + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.amountColor), + fontSize: 30.sp), + ) + ], + ) + ], + ), + SizedBox( + height: 4, + ), + + ///订单编号 + Row( + children: [ + Text( + outputItemStyle.orderIdText, + style: TextStyle( + color: HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['order_id'], + style: TextStyle( + color: HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 28.w, + ), + GestureDetector( + onTap: () { + Clipboard.setData( + ClipboardData(text: modelItem['order_id'])); + Fluttertoast.showToast(msg: "已复制"); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex(outputItemStyle.copyBtnBgColor), + border: Border.all( + color: HexColor.fromHex( + outputItemStyle.contentColor))), + child: Padding( + padding: EdgeInsets.only( + left: 16, right: 16, top: 1, bottom: 1), + child: Text( + outputItemStyle.copyBtnText ?? "", + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + ), + ), + ) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + outputItemStyle.withdrawAccountText, + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['account'] ?? "", + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + ], + )), + Expanded( + child: Row( + children: [ + Text( + outputItemStyle.withdrawAmountText + + " ¥" + + modelItem['amount'], + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + ], + )) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + outputItemStyle.withdrawTimeText, + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['time'] ?? "", + style: TextStyle( + color: HexColor.fromHex("#FF999999"), + fontSize: 22.sp), + ), + ], + )), + Expanded( + child: Row( + children: [ + Text( + outputItemStyle.withdrawOrderStatusText + + " " + + modelItem['order_status'] ?? + "", + style: TextStyle( + color: + HexColor.fromHex(outputItemStyle.contentColor), + fontSize: 22.sp), + ), + ], + )) + ], + ), + ], + ), + ); + } + } + } + + _buildTabViewPage() { + List listWidget = List(); + for (var item in _bloc.styleData.tabList) { + List tabViewBtns; + + if (item.type == 'input') { + tabViewBtns = _bloc.styleData.inputTabViewBtns; + listWidget.add(StreamBuilder( + stream: _bloc.inputOutData, + builder: (context, asny) { + // dataVM = asny.data; + + return Container( + child: Column( + children: [ + _buildType(tabViewBtns, item), + Expanded( + child: SmartRefresher( + controller: _bloc.inputRefreshController, + enablePullDown: true, + enablePullUp: true, + onLoading: () { + _bloc.inputLoad(); + }, + onRefresh: () { + _bloc.inputRefresh(); + }, + child: _bloc.inputDataVM == null + ? Container() + : _buildBottomItem(item)), + ) + ], + ), + ); + })); + } else { + tabViewBtns = _bloc.styleData.outTabViewBtns; + listWidget.add(StreamBuilder( + stream: _bloc.outputOutData, + builder: (context, asny) { + // dataVM = asny.data; + + return Container( + child: Column( + children: [ + _buildType(tabViewBtns, item), + Expanded( + child: SmartRefresher( + controller: _bloc.outputRefreshController, + enablePullDown: true, + enablePullUp: true, + onLoading: () { + _bloc.outputLoad(); + }, + onRefresh: () { + _bloc.outputRefresh(); + }, + child: _bloc.outputDataVM == null + ? Container() + : _buildBottomItem(item)), + ) + ], + ), + ); + })); + } + } + return listWidget; + } + + @override + // TODO: implement wantKeepAlive + bool get wantKeepAlive => true; +} diff --git a/lib/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart b/lib/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart new file mode 100644 index 0000000..196318d --- /dev/null +++ b/lib/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart @@ -0,0 +1,163 @@ +import 'dart:async'; + +import 'package:intl/intl.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; +import 'package:zhiying_comm/util/base_bloc.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +import 'model/wallet_style_model.dart'; + +class WalletBilDetailWidgetBloc extends BlocBase { + StreamController>> inputDataController = + StreamController.broadcast(); + + Stream get inputOutData => inputDataController.stream; + + StreamController>> outputDataController = + StreamController.broadcast(); + + Stream get outputOutData => outputDataController.stream; + + List> inputDataVM; + List> outputDataVM; + + ///样式model + BilDetailStyleModel styleData; + + ///支出当前页数 + int outPutCurrentPage = 1; + + ///收入当前页数 + int inPutCurrentPage = 1; + + ///收入显示时间 + String inputShowDate; + + ///支出显示时间 + String outputShowDate; + + //收入显示类型 + String inputSelectType = 'all'; + + ///支出显示类型 + String outputSelectType = 'all'; + + ///收入下啦刷新 + RefreshController inputRefreshController = RefreshController(); + + ///支出页面下拉刷新 + RefreshController outputRefreshController = RefreshController(); + + @override + void dispose() { + inputDataController.close(); + outputDataController.close(); + inputRefreshController.dispose(); + outputRefreshController.dispose(); + } + + initStyleData(Map data) { + try { + inputShowDate = DateFormat("yyyy-MM").format(DateTime.now()); + outputShowDate = DateFormat("yyyy-MM").format(DateTime.now()); + styleData = BilDetailStyleModel.fromJson(data); + } catch (e, s) { + print(e); + print(s); + } + } + + ///加载收入数据 + loadInputData(int page, String date, {String type}) async { + type = inputSelectType; + String paramsStr = "?page=" + page.toString() + "&time=" + date; + if (type != null && type != "all") { + paramsStr += "&type=" + type; + } + NetUtil.request("/api/v1/user/wallet_detail/input" + paramsStr, + method: NetMethod.GET, onSuccess: (data) { + inputRefreshController.refreshCompleted(); + inputRefreshController.loadComplete(); + var listmap = List.from(data).map((e) { + return e as Map; + }).toList(); + if (inputDataVM == null) { + inputDataVM = List>(); + } + + if (listmap == null || listmap.length == 0) { + inputRefreshController.loadNoData(); + } + + if (inPutCurrentPage == 1) { + inputDataVM.clear(); + inputDataVM.addAll(listmap); + } else { + inputDataVM.addAll(listmap); + } + + refresh(); + }); + } + + ///加载支出数据 + loadOutputData(int page, String date, {String type}) async { + type = outputSelectType; + String paramsStr = "?page=" + page.toString() + "&time=" + date; + if (type != null && type != "all") { + paramsStr += "&type=" + type; + } + NetUtil.request("/api/v1/user/wallet_detail/output" + paramsStr, + method: NetMethod.GET, onSuccess: (data) { + outputRefreshController.refreshCompleted(); + outputRefreshController.loadComplete(); + + var listMap = List.from(data).map((e) { + return e as Map; + }).toList(); + + if (listMap == null || listMap.length == 0) { + outputRefreshController.loadNoData(); + } + if (outputDataVM == null) { + outputDataVM = List(); + } + if (outPutCurrentPage == 1) { + outputDataVM.clear(); + outputDataVM.addAll(listMap); + } else { + outputDataVM.addAll(listMap); + } + refresh(); + }, onError: (e) { + outputRefreshController.refreshCompleted(); + outputRefreshController.loadComplete(); + }); + } + + inputRefresh() { + inPutCurrentPage = 1; + loadInputData(inPutCurrentPage, inputShowDate); + } + + inputLoad() { + inPutCurrentPage++; + loadInputData(inPutCurrentPage, inputShowDate); + } + + outputRefresh() { + outPutCurrentPage = 1; + loadOutputData(outPutCurrentPage, outputShowDate); + } + + outputLoad() { + outPutCurrentPage++; + loadOutputData(outPutCurrentPage, outputShowDate); + } + + ///全刷新 + refresh() { + inputDataController.add(inputDataVM); + outputDataController.add(outputDataVM); + } +} diff --git a/lib/widgets/wallet_bil_detail/wallet_list_widget.dart b/lib/widgets/wallet_bil_detail/wallet_list_widget.dart new file mode 100644 index 0000000..d87aab1 --- /dev/null +++ b/lib/widgets/wallet_bil_detail/wallet_list_widget.dart @@ -0,0 +1,606 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; +import 'package:zhiying_base_widget/dialog/select_date_ym_dialog/select_date_ym_dialog.dart'; +import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_bloc.dart'; +import 'package:zhiying_base_widget/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart'; +import 'package:zhiying_comm/util/base_bloc.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +import 'model/wallet_style_model.dart'; + +class WalletListWidget extends StatefulWidget { + final TabList tabList; + final List tabViewBtns; + const WalletListWidget({Key key,this.tabViewBtns, this.tabList}) : super(key: key); + @override + _WalletListWidgetState createState() => _WalletListWidgetState(); +} + +class _WalletListWidgetState extends State with AutomaticKeepAliveClientMixin { + WalletBilDetailWidgetBloc _bloc; + List tabViewBtns; + TabList item; + + @override + void initState() { + item=widget.tabList; + tabViewBtns=widget.tabViewBtns; + super.initState(); + } + + @override + Widget build(BuildContext context) { + _bloc = BlocProvider.of(context); + if(item.type=='input'){ + return StreamBuilder( + stream: _bloc.inputOutData, + builder: (context, asny) { + // dataVM = asny.data; + + return Container( + child: Column( + children: [ + _buildType(tabViewBtns, item), + Expanded( + child: SmartRefresher( + controller: _bloc.inputRefreshController, + enablePullDown: true, + enablePullUp: true, + onLoading: _bloc.outputLoad(), + onRefresh: _bloc.outputRefresh(), + child: _bloc.inputDataVM == null + ? Container() + : _buildBottomItem(item)), + ) + ], + ), + ); + }); + }else{ + return StreamBuilder( + stream: _bloc.outputOutData, + builder: (context, asny) { + // dataVM = asny.data; + + return Container( + child: Column( + children: [ + _buildType(tabViewBtns, item), + Expanded( + child: SmartRefresher( + controller: _bloc.outputRefreshController, + enablePullDown: true, + enablePullUp: true, + onLoading: _bloc.outputLoad(), + onRefresh: _bloc.outputRefresh(), + child: _bloc.outputDataVM == null + ? Container() + : _buildBottomItem(item)), + ) + ], + ), + ); + }); + } + + + } + + + + _buildType(List tabViewBtns, TabList tabList) { + var selectType; + if (tabList.type == 'input') { + selectType = _bloc.inputSelectType; + } else { + selectType = _bloc.outputSelectType; + ; + } + return Row( + children: [ + SizedBox(width: 12.5), + InkWell( + onTap: () { + ///显示日期选择弹窗 + _selectDate(tabList); + }, + child: Padding( + padding: const EdgeInsets.only(top: 8, bottom: 8), + child: Text( + tabList.type == "input" + ? _bloc.inputShowDate + : _bloc.outputShowDate, + style: TextStyle( + fontSize: 28.sp, + color: + HexColor.fromHex(_bloc.styleData.timeSelectColor)))), + ), + Icon( + Icons.arrow_drop_down, + color: HexColor.fromHex(_bloc.styleData.timeSelectColor), + ), + Expanded( + child: Container( + height: 50, + child: ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: tabViewBtns.length, + itemBuilder: (context, index) { + return InkWell( + onTap: () async { + if (tabList.type == 'input') { + _bloc.inputSelectType = tabViewBtns[index].type; + _bloc.loadInputData( + _bloc.inPutCurrentPage, _bloc.inputShowDate, + type: _bloc.inputSelectType); + } else { + _bloc.outputSelectType = tabViewBtns[index].type; + _bloc.loadOutputData( + _bloc.outPutCurrentPage, _bloc.outputShowDate, + type: _bloc.outputSelectType); + } + _bloc.refresh(); + }, + child: Container( + margin: EdgeInsets.only( + top: 10, left: 8, right: 8, bottom: 10), + decoration: BoxDecoration( + border: Border.all( + color: HexColor.fromHex( + selectType == tabViewBtns[index].type + ? _bloc.styleData.btnSelectedColor + : _bloc.styleData.btnNoSelectedColor), + ), + borderRadius: BorderRadius.circular(50)), + child: Padding( + padding: EdgeInsets.only(left: 16, right: 16), + child: Center( + child: Text( + tabViewBtns[index].name ?? "", + style: TextStyle( + color: HexColor.fromHex( + selectType == tabViewBtns[index].type + ? _bloc.styleData.btnSelectedColor + : _bloc.styleData.btnNoSelectedColor)), + )), + ), + )); + }), + )) + ], + ); + } + + _selectDate(TabList tabList) async { + var result = await showDialog( + context: context, builder: (context) => SelectDateYMDialog()); + if (result != null) { + var dataTime = DateFormat('yyyy-MM').format( + DateTime(int.parse(result['year']), int.parse(result['month']))); + if (tabList.type == "input") { + _bloc.inputShowDate = dataTime; + _bloc.loadInputData(_bloc.inPutCurrentPage, _bloc.inputShowDate); + } else { + _bloc.outputShowDate = dataTime; + _bloc.loadInputData(_bloc.outPutCurrentPage, _bloc.outputShowDate); + } + _bloc.refresh(); + } + } + + + + + _buildBottomItem(TabList tabList) { + return ListView.builder( + shrinkWrap: true, + itemCount: tabList.type == 'input' + ? _bloc.inputDataVM?.length??0 + : _bloc.outputDataVM?.length??0, + itemBuilder: (context, index) { + return _buildItem(context, index, tabList); + }); + } + + Widget _buildItem(BuildContext context, int index, TabList tabList) { + if (tabList.type == 'input') { + InputItemStyle inputItemStyle = _bloc.styleData.inputItemStyle; + var modelItem = _bloc.inputDataVM[index]; + return Container( + margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), + padding: + EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), + decoration: BoxDecoration( + color: HexColor.fromHex("#FFFFFF"), + borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex("#FFFFF3F3"), + border: Border.all( + color: HexColor.fromHex( + inputItemStyle.typeNameColor))), + child: Padding( + padding: const EdgeInsets.only( + left: 4, right: 4, top: 2, bottom: 2), + child: Center( + child: Text( + modelItem['type'] ?? "", + style: TextStyle( + color: HexColor.fromHex( + inputItemStyle.typeNameColor), + fontSize: 20.sp), + ), + ), + ), + ), + Container( + width: 353.w, + margin: EdgeInsets.only(left: 15.w), + child: Text( + modelItem['title'] ?? "", + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 28.sp), + )) + ], + ), + Row( + children: [ + Text( + "+ ", + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.amountColor)), + ), + Text( + "¥ " + modelItem['amount'], + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.amountColor), + fontSize: 30.sp), + ) + ], + ) + ], + ), + SizedBox( + height: 4, + ), + + ///订单编号 + Row( + children: [ + Text( + inputItemStyle.orderIdText, + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['order_id'], + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 28.w, + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex(inputItemStyle.copyBtnBgColor), + border: Border.all( + color: + HexColor.fromHex(inputItemStyle.contentColor))), + child: Padding( + padding: + EdgeInsets.only(left: 16, right: 16, top: 1, bottom: 1), + child: Text( + inputItemStyle.copyBtnText, + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + ), + ) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.orderTypeText, + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['order_type'] ?? "", + style: TextStyle( + color: HexColor.fromHex("#FF999999"), + fontSize: 22.sp), + ), + ], + )), + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.amountText + " ¥" + modelItem['amount'], + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + ], + )) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.timeText, + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['time'] ?? "", + style: TextStyle( + color: HexColor.fromHex("#FF999999"), + fontSize: 22.sp), + ), + ], + )), + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.settleTimeText + + " " + + modelItem['settle_time'] ?? + "", + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + ], + )) + ], + ), + ], + ), + ); + } else if (tabList.type == 'output') { + OutputItemStyle inputItemStyle = _bloc.styleData.outputItemStyle; + var modelItem = _bloc.outputDataVM[index]; + if (modelItem['type'] == '消费') { + ///消费返回的Item + return Container( + margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), + padding: + EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), + decoration: BoxDecoration( + color: HexColor.fromHex("#FFFFFF"), + borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex("#FFFFF3F3"), + border: Border.all( + color: HexColor.fromHex( + inputItemStyle.typeNameColor))), + child: Padding( + padding: const EdgeInsets.only( + left: 4, right: 4, top: 2, bottom: 2), + child: Center( + child: Text( + modelItem['type'] ?? "", + style: TextStyle( + color: HexColor.fromHex( + inputItemStyle.typeNameColor), + fontSize: 20.sp), + ), + ), + ), + ), + Container( + width: 353.w, + margin: EdgeInsets.only(left: 15.w), + child: Text( + modelItem['title'] ?? "", + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 28.sp), + )) + ], + ), + Row( + children: [ + Text( + "- ", + style: TextStyle(color: Colors.red), + ), + Text( + "¥ " + modelItem['amount'], + style: TextStyle(color: Colors.red, fontSize: 30.sp), + ) + ], + ) + ], + ), + SizedBox( + height: 4, + ), + + ///订单编号 + Row( + children: [ + Text( + inputItemStyle.orderIdText, + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['order_id'], + style: TextStyle( + color: HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 28.w, + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: HexColor.fromHex(inputItemStyle.copyBtnBgColor), + border: Border.all( + color: + HexColor.fromHex(inputItemStyle.contentColor))), + child: Padding( + padding: EdgeInsets.only( + left: 16, right: 16, top: 1, bottom: 1), + child: Text( + inputItemStyle.copyBtnText ?? "", + style: TextStyle( + color: + HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + ), + ) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.consumeOrderTypeText, + style: TextStyle( + color: + HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['order_type'] ?? "", + style: TextStyle( + color: HexColor.fromHex("#FF999999"), + fontSize: 22.sp), + ), + ], + )), + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.consumeAmountText + + " ¥" + + modelItem['amount'], + style: TextStyle( + color: + HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + ], + )) + ], + ), + SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: Row( + children: [ + Text( + inputItemStyle.consumeTimeText, + style: TextStyle( + color: + HexColor.fromHex(inputItemStyle.contentColor), + fontSize: 22.sp), + ), + SizedBox( + width: 4, + ), + Text( + modelItem['time'] ?? "", + style: TextStyle( + color: HexColor.fromHex("#FF999999"), + fontSize: 22.sp), + ), + ], + )), + // Expanded( + // child: Row( + // children: [ + // Text( + // inputItemStyle.consumeTimeText + + // " " + + // modelItem['settle_time'] ?? + // "", + // style: TextStyle( + // color: HexColor.fromHex(inputItemStyle.contentColor), + // fontSize: 22.sp), + // ), + // ], + // )) + ], + ), + ], + ), + ); + } else {} + } + } + + @override + // TODO: implement wantKeepAlive + bool get wantKeepAlive => true; +} From 4df30af8264ee11e7b91cb92622a2c24a02d81cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=8D=8E=E8=BD=A9?= <646903573@qq.com> Date: Mon, 2 Nov 2020 18:53:37 +0800 Subject: [PATCH 6/6] =?UTF-8?q?1.=E9=92=B1=E5=8C=85=E6=98=8E=E7=BB=86?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=AA=A8=E6=9E=B6=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bil_detail_page/bil_detail_page.dart | 4 +- .../wallet_bil_detail/wallet_bil_sk.dart | 211 ++++++++++++++++++ 2 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 lib/widgets/wallet_bil_detail/wallet_bil_sk.dart diff --git a/lib/pages/bil_detail_page/bil_detail_page.dart b/lib/pages/bil_detail_page/bil_detail_page.dart index 4da82d7..13f9cd5 100644 --- a/lib/pages/bil_detail_page/bil_detail_page.dart +++ b/lib/pages/bil_detail_page/bil_detail_page.dart @@ -10,6 +10,8 @@ import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifi import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart'; import 'package:zhiying_base_widget/utils/contants.dart'; import 'package:zhiying_base_widget/widgets/others/mine_header_bg_widget.dart'; +import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_sk.dart'; +import 'package:zhiying_base_widget/widgets/wallet_bil_detail/wallet_bil_sk.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; import 'package:zhiying_comm/util/base_bloc.dart'; import 'package:zhiying_comm/util/custom_sliver_persistent_header_delegate.dart'; @@ -73,7 +75,7 @@ class _BilDetailPageContainerState extends State { stream: _bloc.outData, builder: (context, sny) { if (sny.data == null) { - return Container(); + return WalletBilDetailSkeleton(); } var model = sny.data; return Scaffold( diff --git a/lib/widgets/wallet_bil_detail/wallet_bil_sk.dart b/lib/widgets/wallet_bil_detail/wallet_bil_sk.dart new file mode 100644 index 0000000..4de4555 --- /dev/null +++ b/lib/widgets/wallet_bil_detail/wallet_bil_sk.dart @@ -0,0 +1,211 @@ +import 'package:flutter/material.dart'; +import 'package:shimmer/shimmer.dart'; + +class WalletBilDetailSkeleton extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + child: Shimmer.fromColors( + baseColor: Colors.grey[300], + highlightColor: Colors.grey[100], + child: Column( + children: [ + Container( + color: Colors.white, + height: 80, + ), + SizedBox( + height: 32, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + color: Colors.white, + height: 40, + width: 100, + ), + Container( + color: Colors.white, + height: 40, + width: 100, + ) + ], + ), + SizedBox( + height: 16, + ), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 40, + width: 80, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 40, + width: 80, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 40, + width: 80, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 40, + width: 80, + ) + ], + ), + Expanded( + child: ListView.builder( + itemCount: 3, + itemBuilder: _buildItem, + )) + ], + )), + ); + } + + Widget _buildItem(BuildContext context, int index) { + return Container( + margin: EdgeInsets.all(16), + child: Column( + children: [ + Row( + children: [ + Container( + color: Colors.white, + height: 20, + width: 40, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 20, + width: 100, + ) + ], + ), + SizedBox( + height: 8, + ), + Row( + children: [ + Container( + color: Colors.white, + height: 20, + width: 40, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 20, + width: 120, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 20, + width: 40, + ) + ], + ), + SizedBox( + height: 8, + ), + Row( + children: [ + Container( + color: Colors.white, + height: 20, + width: 40, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 20, + width: 100, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 20, + width: 40, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 20, + width: 100, + ), + ], + ), + SizedBox( + height: 8, + ), + Row( + children: [ + Container( + color: Colors.white, + height: 20, + width: 40, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 20, + width: 100, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 20, + width: 40, + ), + SizedBox( + width: 16, + ), + Container( + color: Colors.white, + height: 20, + width: 100, + ), + ], + ) + ], + ), + ); + } +}