diff --git a/example/lib/main.dart b/example/lib/main.dart index c763839..cb9203d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -61,6 +61,10 @@ class _MyAppState extends State { ChangeNotifierProvider.value(value: UserInfoNotifier()), ], child: MaterialApp( + theme: ThemeData( + primaryColor: HexColor.fromHex('#FF4242'), + accentColor: HexColor.fromHex('#FF4242'), + ), routes: { '/homePage': (BuildContext context) => HomePage() , }, diff --git a/lib/dialog/global_dialog/activity_dialog/activity_dialog.dart b/lib/dialog/global_dialog/activity_dialog/activity_dialog.dart new file mode 100644 index 0000000..04f6039 --- /dev/null +++ b/lib/dialog/global_dialog/activity_dialog/activity_dialog.dart @@ -0,0 +1,84 @@ +import 'dart:convert'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'activity_dialog_model.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +/// +/// 活动弹窗接口 +/// +class ActivityDialog extends StatelessWidget { + final ActivityDialogModel model; + + const ActivityDialog(this.model, {Key key}) : super(key: key); + + static Future show(BuildContext context) async { + try { + Map result = await NetUtil.post('/api/v1/mod/pub.flutter.current_activity_dialog', method: NetMethod.GET); + if (!EmptyUtil.isEmpty(result)) { + var modListData = result['data']['mod_list'][0]['data']; + if (!EmptyUtil.isEmpty(modListData)) { + Map da = Map.from(jsonDecode(modListData)); + ActivityDialogModel model = ActivityDialogModel.fromJson(Map.from(da)); + if(!EmptyUtil.isEmpty(model) && model.isOpen == '1' ) { + return await showCupertinoDialog(context: context, builder: (_) => ActivityDialog(model)); + } + } + } + } catch (e, s) { + Logger.error(e, s); + } + } + + /// 跳转 + void _jumpTo(BuildContext context){ + Navigator.maybePop(context); + if(!EmptyUtil.isEmpty(model)){ + RouterUtil.route(model, model.toJson(), context); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.transparent, + body: Container( + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + + /// 图片 + GestureDetector( + onTap: ()=> _jumpTo(context), + behavior: HitTestBehavior.opaque, + child: Container( + // margin: const EdgeInsets.symmetric(horizontal: 40), + width: MediaQuery.of(context).size.width * 0.7, + child: CachedNetworkImage( + imageUrl: model?.img ?? '', + ), + ), + ), + + /// 关闭按钮 + GestureDetector( + child: Container( + width: 30, + height: 30, + margin: EdgeInsets.only(top: 10), + child: CachedNetworkImage(imageUrl: model?.btnImg ?? '',), + ), + onTap: () { + Navigator.pop(context); + }, + ) + ], + ), + ), + ); + } +} diff --git a/lib/dialog/global_dialog/activity_dialog/activity_dialog_model.dart b/lib/dialog/global_dialog/activity_dialog/activity_dialog_model.dart new file mode 100644 index 0000000..7484a67 --- /dev/null +++ b/lib/dialog/global_dialog/activity_dialog/activity_dialog_model.dart @@ -0,0 +1,43 @@ +import 'package:zhiying_comm/zhiying_comm.dart'; + +class ActivityDialogModel extends SkipModel { + String isOpen; + String name; + String img; + String btnImg; + String skipType; + String url; + String skipIdentifier; + + ActivityDialogModel( + {this.isOpen, + this.name, + this.img, + this.btnImg, + this.skipType, + this.url, + this.skipIdentifier}); + + ActivityDialogModel.fromJson(Map json) { + super.fromJson(json); + isOpen = json['is_open']; + name = json['name']; + img = json['img']; + btnImg = json['btn_img']; + skipType = json['skip_type']; + url = json['url']; + skipIdentifier = json['skip_identifier']; + } + + Map toJson() { + final Map data = super.toJson(); + data['is_open'] = this.isOpen; + data['name'] = this.name; + data['img'] = this.img; + data['btn_img'] = this.btnImg; + data['skip_type'] = this.skipType; + data['url'] = this.url; + data['skip_identifier'] = this.skipIdentifier; + return data; + } +} diff --git a/lib/pages/custom_page/bloc/custom_page_repository.dart b/lib/pages/custom_page/bloc/custom_page_repository.dart index 72db1ed..c6db1be 100644 --- a/lib/pages/custom_page/bloc/custom_page_repository.dart +++ b/lib/pages/custom_page/bloc/custom_page_repository.dart @@ -10,6 +10,7 @@ class CustomPageRepository { try { String skipIdentifier = !EmptyUtil.isEmpty(data) && data.containsKey(GlobalConfig.SKIP_IDENTIFIER) && !EmptyUtil.isEmpty(data[GlobalConfig.SKIP_IDENTIFIER]) ? data[GlobalConfig.SKIP_IDENTIFIER] : null; + // String skipIdentifier = 'pub.flutter.index.84'; if (!EmptyUtil.isEmpty(skipIdentifier)) { var result = await NetUtil.post('/api/v1/mod/$skipIdentifier', method: NetMethod.GET, cache: true); if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { @@ -30,6 +31,7 @@ class CustomPageRepository { try { String skipIdentifier = !EmptyUtil.isEmpty(data) && data.containsKey(GlobalConfig.SKIP_IDENTIFIER) && !EmptyUtil.isEmpty(data[GlobalConfig.SKIP_IDENTIFIER]) ? data[GlobalConfig.SKIP_IDENTIFIER] : null; + // String skipIdentifier = 'pub.flutter.index.84'; if (!EmptyUtil.isEmpty(skipIdentifier)) { var result = await NetUtil.getRequestCachedData('/api/v1/mod/$skipIdentifier'); if (!EmptyUtil.isEmpty(result)) { diff --git a/lib/pages/custom_page/custom_item_page.dart b/lib/pages/custom_page/custom_item_page.dart index 9d813e8..ccdb0b0 100644 --- a/lib/pages/custom_page/custom_item_page.dart +++ b/lib/pages/custom_page/custom_item_page.dart @@ -11,6 +11,8 @@ import 'bloc/custom_item_page_bloc.dart'; import 'bloc/custom_item_page_state.dart'; import 'bloc/custom_item_page_event.dart'; import 'bloc/custom_item_page_repository.dart'; +import 'dart:ui'; +import 'package:zhiying_comm/util/custom_sliver_persistent_header_delegate.dart'; /// /// 通用模块的分类导航下的子模块 @@ -21,8 +23,9 @@ class CustomItemPage extends StatelessWidget { final int tabIndex; final String modPid; final String modId; + final bool needBuildStatus; - CustomItemPage(this.data, this.tabIndex, this.modId, this.modPid); + CustomItemPage(this.data, this.tabIndex, this.modId, this.modPid, this.needBuildStatus); @override Widget build(BuildContext context) { @@ -32,13 +35,7 @@ class CustomItemPage extends StatelessWidget { ], child: BlocProvider( create: (_) => CustomItemPageBloc(CustomItemPageRepository(this.data, this.tabIndex, this.modId, this.modPid)), - child: _CustomItemPageContainer( - this.data, - this.tabIndex, - this.modId, - this.modPid, - key: UniqueKey(), - ), + child: _CustomItemPageContainer(this.data, this.tabIndex, this.modId, this.modPid, this.needBuildStatus), ), ); } @@ -49,8 +46,9 @@ class _CustomItemPageContainer extends StatefulWidget { final int tabIndex; final String modPid; final String modId; + final bool needBuildStatus; - const _CustomItemPageContainer(this.data, this.tabIndex, this.modId, this.modPid, {Key key}) : super(key: key); + const _CustomItemPageContainer(this.data, this.tabIndex, this.modId, this.modPid, this.needBuildStatus, {Key key}) : super(key: key); @override __CustomItemPageContainerState createState() => __CustomItemPageContainerState(); @@ -83,7 +81,7 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit void _loadEvent() { // BlocProvider.of(context).add(CustomItemPageLoadEvent()); Provider.of(context, listen: false).loadMore(); - Future.delayed(Duration(seconds: 1),()=> _refreshController?.loadComplete()); + Future.delayed(Duration(milliseconds: 500), () => _refreshController?.loadComplete()); } @override @@ -146,7 +144,7 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit Widget _buildMainWidget(final List> model) { return MediaQuery.removePadding( context: context, - removeTop: true, + removeTop: false, child: SmartRefresher( controller: _refreshController, enablePullDown: true, @@ -154,7 +152,7 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit onRefresh: _refreshEvent, onLoading: _loadEvent, header: RefreshHeader(), - footer: RefreshFooter(), + // footer: RefreshFooter(), child: CustomScrollView( controller: _controller, slivers: _buildContentWidgets(model), @@ -174,13 +172,34 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit model: datas[i], )); } + + if (widget.needBuildStatus) { + double top = MediaQueryData.fromWindow(window).padding.top; + result.insert( + 0, + SliverPersistentHeader( + pinned: true, + floating: false, + delegate: CustomSliverPersistentHeaderDelegate(max: top, min: top, child: Container( + // color: Colors.yellow, + color: HexColor.fromHex('#FFFF4242'), + )), + )); + + } + return result; } /// 空数据 Widget _buildEmptyWidget() { - return Container( - child: EmptyWidget(), + return SmartRefresher( + controller: _refreshController, + onRefresh: _refreshEvent, + enablePullDown: true, + child: Container( + child: EmptyWidget(), + ), ); } diff --git a/lib/pages/custom_page/custom_page.dart b/lib/pages/custom_page/custom_page.dart index dab0e5c..68e30d5 100644 --- a/lib/pages/custom_page/custom_page.dart +++ b/lib/pages/custom_page/custom_page.dart @@ -7,6 +7,7 @@ import 'package:zhiying_base_widget/pages/custom_page/custom_item_page.dart'; import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart'; import 'package:zhiying_base_widget/widgets/custom/search/custom_search_widget.dart'; import 'package:zhiying_base_widget/widgets/empty/empty_widget.dart'; +import 'package:zhiying_base_widget/widgets/others/mine_header_bg_widget.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -21,21 +22,25 @@ import 'package:fluttertoast/fluttertoast.dart'; /// /// 通用模块页面 /// -class CustomPage extends StatelessWidget { +class CustomPage extends StatefulWidget { final Map data; CustomPage(this.data, {Key key}) : super(key: key); + @override + _CustomPageState createState() => _CustomPageState(); +} + +class _CustomPageState extends State { @override Widget build(BuildContext context) { - // return NestedScrollDemoPage(); return MultiProvider( providers: [ ChangeNotifierProvider.value(value: MainPageBgNotifier()), ], child: BlocProvider( - create: (_) => CustomPageBloc(CustomPageRepository(data: data))..add(CustomPageInitEvent()), - child: _CommonPageContainer(data), + create: (_) => CustomPageBloc(CustomPageRepository(data: widget?.data))..add(CustomPageInitEvent()), + child: _CommonPageContainer(widget?.data), // ), ), ); @@ -54,6 +59,12 @@ class _CommonPageContainer extends StatefulWidget { class __CommonPageContainerState extends State<_CommonPageContainer> with SingleTickerProviderStateMixin { TabController _tabController; + // 是否有AppBar + bool _isHasAppbar = false; + + // 是否有TabBar + bool _isHasTabBar = false; + /// 刷新 void _onRefreshEvent() async { BlocProvider.of(context).add(CustomPageRefreshEvent()); @@ -106,14 +117,36 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single /// 有数据 Widget _buildMainWidget(List> model) { - return Scaffold( - appBar: _buildAppbar(model?.first), - backgroundColor: HexColor.fromHex('#F9F9F9'), - // floatingActionButton: _buildFloatWidget(), - floatingActionButtonLocation: _CustomFloatingActionButtonLocation(FloatingActionButtonLocation.endFloat, 0, -100), - body: Column( - children: _buildFirstWidget(model), - ), + return Stack( + children: [ + // 背景 + Column( + children: [ + // Container( + // width: double.infinity, + // height: 190, + // color: HexColor.fromHex('#FF4242'), + // ), + Expanded( + child: Container( + height: double.infinity, + width: double.infinity, + color: HexColor.fromHex('#F9F9F9'), + ), + ) + ], + ), + + // MineHeaderBgWidget(controller: null), + + Scaffold( + appBar: _buildAppbar(model?.first), + backgroundColor: Colors.transparent, + // floatingActionButton: _buildFloatWidget(), + floatingActionButtonLocation: _CustomFloatingActionButtonLocation(FloatingActionButtonLocation.endFloat, 0, -100), + body: Column(children: _buildFirstWidget(model)), + ), + ], ); } @@ -177,7 +210,7 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single List result = []; // 分类导航的key ⚠️ 这里先写成Test 后续要改 - const String CATEGORY_KEY = 'category_test'; + const String CATEGORY_KEY = 'category'; // 判断是否有分类导航 // 判断最后一个是否属于分类导航,如果属于,则有分类导航,如果不是,则无分类导航 bool haveCategory = !EmptyUtil.isEmpty(model?.last) && model.last.containsKey('mod_name') && model.last['mod_name'] == CATEGORY_KEY; @@ -197,7 +230,7 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single WidgetModel item = WidgetModel.fromJson(Map.from(model[i])); // last model if (i == endIndexLength - 1) { - result.addAll(_buildTabBar(model[i])); + result.addAll(_buildTabBar(model[i], i)); break; } @@ -205,12 +238,12 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single if (item.modName.contains('appbar')) { continue; } + result.addAll(WidgetFactory.create(item.modName, isSliver: false, model: model[i])); + } - result.addAll(WidgetFactory.create( - item.modName, - isSliver: false, - model: model[i], - )); + // 没有appbar并且有tabbar,则给第一个元素加边距 + if (!_isHasAppbar && _isHasTabBar) { + result.insert(0, SizedBox(height: MediaQueryData.fromWindow(window).padding.top)); } return result; @@ -227,9 +260,8 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single } catch (e, s) { Logger.warn(e, s); } - String parentTitle = !EmptyUtil.isEmpty(widget?.data) ? widget?.data['title_1'] ?? '' : ''; - + _isHasAppbar = true; return AppBar( backgroundColor: HexColor.fromHex(null != data ? data['app_bar_bg_color'] ?? '#FFFFFF' : '#FFFFFF'), brightness: Brightness.light, @@ -255,7 +287,7 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single } /// tabBar - List _buildTabBar(final Map model) { + List _buildTabBar(final Map model, final int index) { Map data = Map(); List> listStyle = []; List result = []; @@ -269,7 +301,7 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single // 1、导航栏没开启的情况 传null进去进行获取没开启导航栏的widget集合 if (EmptyUtil.isEmpty(listStyle)) { result.add(Expanded( - child: CustomItemPage(null, 0, model['mod_id']?.toString() ?? null, model['mod_pid']?.toString() ?? null), + child: CustomItemPage(null, 0, model['mod_id']?.toString() ?? null, model['mod_pid']?.toString() ?? null, (!_isHasAppbar && index == 0 )), )); return result; } @@ -280,10 +312,11 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single if (null == _tabController || _tabController.length != listStyle.length) { _tabController = new TabController(length: listStyle.length, vsync: this); } + result.add(Container( height: 40, width: double.infinity, - color: HexColor.fromHex('#FFFFFF'), + // color: HexColor.fromHex('#FFFFFF'), child: TabBar( controller: _tabController, isScrollable: /*listStyle.length <= 5 ? false : */ true, @@ -305,11 +338,12 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single ), )); + _isHasTabBar = true; // 最后添加TabBarView result.add(Expanded( child: TabBarView( controller: _tabController, - children: _buildTabBarViewChildren(listStyle, model['mod_id']?.toString(), model['mod_pid']?.toString()), + children: _buildTabBarViewChildren(listStyle, model['mod_id']?.toString(), model['mod_pid']?.toString(), index), ), )); } @@ -317,10 +351,10 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single } /// 返回TabBarView的视图 - List _buildTabBarViewChildren(final List> listStyle, final String modId, final String modPid) { + List _buildTabBarViewChildren(final List> listStyle, final String modId, final String modPid, final int index) { List result = []; for (int i = 0; i < listStyle.length; i++) { - result.add(CustomItemPage(listStyle[i], i, modId, modPid)); + result.add(CustomItemPage(listStyle[i], i, modId, modPid, (!_isHasAppbar && !_isHasTabBar && index == 0 ))); } return result; } diff --git a/lib/pages/home_page/home_page.dart b/lib/pages/home_page/home_page.dart index 186192a..369f917 100644 --- a/lib/pages/home_page/home_page.dart +++ b/lib/pages/home_page/home_page.dart @@ -8,6 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:moblink/moblink.dart'; import 'package:provider/provider.dart'; +import 'package:zhiying_base_widget/dialog/global_dialog/activity_dialog/activity_dialog.dart'; import 'package:zhiying_base_widget/dialog/global_dialog/intellect_search_goods_dialog/intellect_create.dart'; import 'package:zhiying_base_widget/dialog/global_dialog/notification_setting_dialog/notification_setting_dialog.dart'; import 'package:zhiying_base_widget/dialog/global_dialog/policy_dialog/policy_dialog.dart'; @@ -15,6 +16,7 @@ import 'package:zhiying_base_widget/utils/contants.dart'; import 'package:zhiying_comm/models/base/base_tab_model.dart'; import 'package:zhiying_comm/util/image_util.dart'; import 'package:zhiying_comm/util/mob_util/mob_util.dart'; +import 'package:sharesdk_plugin/sharesdk_plugin.dart'; import 'package:zhiying_comm/util/shared_prefe_util.dart'; import 'package:zhiying_comm/util/update/app_update_util.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; @@ -49,10 +51,11 @@ class _HomePageState extends State with WidgetsBindingObserver { AppUpdateUtil.updateApp(context); TaobaoAuth.initAuth(context); + // 弹窗 _showPolicy(); Moblink.uploadPrivacyPermissionStatus(1, (bool success) {}); - + SharesdkPlugin.uploadPrivacyPermissionStatus( 1 , (bool success) {}); // 是安卓系统,Android场景还原的实现 /*if (defaultTargetPlatform == TargetPlatform.android) { @@ -179,9 +182,15 @@ class _HomePageState extends State with WidgetsBindingObserver { return true; } + /// + /// 各种弹窗 + /// 1、用户协议弹窗 + /// 2、通知栏开启弹窗 + /// 3、活动弹窗 + /// Future _showPolicy() async { - String isShowPolicy = - await SharedPreferencesUtil.getStringValue(Constants.isShowPolicy); + // 协议弹窗 + String isShowPolicy = await SharedPreferencesUtil.getStringValue(Constants.isShowPolicy); if (isShowPolicy == null || isShowPolicy != '1') { bool isAccept = await PolicyDialog.show(context); if (!isAccept) { @@ -191,14 +200,17 @@ class _HomePageState extends State with WidgetsBindingObserver { } } + // 通知弹窗 String isShowNotiPermission = await SharedPreferencesUtil.getStringValue( Constants.isShowNotiPermission); if (isShowNotiPermission == null || isShowNotiPermission != '1') { await NotificationSettingDialog.show(context); - await SharedPreferencesUtil.setStringValue( - Constants.isShowNotiPermission, "1"); + await SharedPreferencesUtil.setStringValue(Constants.isShowNotiPermission, "1"); } + // 活动弹窗 + await ActivityDialog.show(context); + IntellectCreate.checkAndCreateFirst(context); } diff --git a/lib/register.dart b/lib/register.dart index 341b959..cd9d435 100644 --- a/lib/register.dart +++ b/lib/register.dart @@ -34,6 +34,8 @@ import 'package:zhiying_base_widget/pages/team_page/team_page.dart'; import 'package:zhiying_base_widget/pages/webview/base_webview.dart'; import 'package:zhiying_base_widget/pages/wechat_teacher_page/wechat_teacher_page.dart'; import 'package:zhiying_base_widget/pages/withdraw_page/withdraw_page.dart'; +import 'package:zhiying_base_widget/widgets/custom/banner/custom_banner_widget.dart'; +import 'package:zhiying_base_widget/widgets/custom/goods/custom_goods_widget.dart'; import 'package:zhiying_base_widget/widgets/custom/multi_nav/custom_quick_entry.dart'; import 'package:zhiying_base_widget/widgets/custom/search/custom_search_widget.dart'; import 'package:zhiying_base_widget/widgets/custom/slide_banner/custom_slide_banner_creater.dart'; @@ -107,29 +109,23 @@ class BaseWidgetRegister { AppConfigModel config = await AppConfigModel.init(); if (config == null) { Logger.debug('app 初始化失败'); - return ; + return; } ShareSDKRegister register = ShareSDKRegister(); // ================ Weixin - register.setupWechat(config.keys?.weixin?.appId ?? '', - config.keys?.weixin?.secret ?? '', config.keys?.weixin?.universalLink ?? ''); + register.setupWechat(config.keys?.weixin?.appId ?? '', config.keys?.weixin?.secret ?? '', config.keys?.weixin?.universalLink ?? ''); // ================ Weibo - register.setupSinaWeibo(config.keys?.weibo?.appkey ?? '', config.keys?.weibo?.secret ?? '', - config.keys?.weibo?.redirectUrl ?? ''); + register.setupSinaWeibo(config.keys?.weibo?.appkey ?? '', config.keys?.weibo?.secret ?? '', config.keys?.weibo?.redirectUrl ?? ''); // ================ QQ register.setupQQ(config.keys?.qq?.appId ?? '', config.keys?.qq?.appkey ?? ''); // ================ jd if (Platform.isIOS) { - Jdsdk.init( - appKey: config.keys?.jdIos?.appkey ?? '', - appSecret: config.keys?.jdIos?.secret ?? ''); + Jdsdk.init(appKey: config.keys?.jdIos?.appkey ?? '', appSecret: config.keys?.jdIos?.secret ?? ''); } else if (Platform.isAndroid) { - Jdsdk.init( - appKey: config.keys?.jdAndroid?.appkey ?? '', - appSecret: config.keys?.jdAndroid?.secret ?? ''); + Jdsdk.init(appKey: config.keys?.jdAndroid?.appkey ?? '', appSecret: config.keys?.jdAndroid?.secret ?? ''); } SharesdkPlugin.regist(register); }); @@ -153,7 +149,6 @@ class BaseWidgetRegister { NetUtil.post('/api/v1/rec/suning?page=1', method: NetMethod.GET, cache: true); // 考拉 NetUtil.post('/api/v1/rec/kaola?page=1', method: NetMethod.GET, cache: true); - return null; }); @@ -161,70 +156,54 @@ class BaseWidgetRegister { Application.addMethod(() async { return Future.delayed(Duration(seconds: 1)); }); - - } // 注册页面 static void registPage() { PageFactory.regist('LaunchPage', (model) => LaunchPage()); // PageFactory.regist('homePage', (model) => HomePage()); - PageFactory.regist('pub.flutter.index', (model) => MainPage(model)); + // PageFactory.regist('pub.flutter.index', (model) => MainPage(model)); + PageFactory.regist('pub.flutter.index', (model) => CustomPage(model)); PageFactory.regist('pub.flutter.profile', (model) => MainPage(model)); - PageFactory.regist( - 'pub.flutter.hot_rank', (model) => HotRankingPage(model)); - PageFactory.regist( - 'pub.flutter.my_wallet', (model) => WalletPage(data: model)); + PageFactory.regist('pub.flutter.hot_rank', (model) => HotRankingPage(model)); + PageFactory.regist('pub.flutter.my_wallet', (model) => WalletPage(data: model)); PageFactory.regist('goods_details', (model) => GoodsDetailsPage(model)); - PageFactory.regist( - 'pub.flutter.search_index', (model) => SearchPage(model)); + PageFactory.regist('pub.flutter.search_index', (model) => SearchPage(model)); PageFactory.regist('search_item_page', (model) => SearchItemPage(model)); - PageFactory.regist( - 'pub.flutter.search_result', (model) => SearchResultPage(model)); - PageFactory.regist( - 'search_result_item', (model) => SearchResultItemPage(model)); + PageFactory.regist('pub.flutter.search_result', (model) => SearchResultPage(model)); + PageFactory.regist('search_result_item', (model) => SearchResultItemPage(model)); PageFactory.regist('pub.flutter.feedback', (model) => FeedbackPage(model)); PageFactory.regist('pub.flutter.feedback_list', (model) => FeedbackRecordPage(model)); - PageFactory.regist( - 'pub.flutter.wechat_teacher', (model) => WechatTeacherPage(model)); + PageFactory.regist('pub.flutter.wechat_teacher', (model) => WechatTeacherPage(model)); PageFactory.regist('pub.flutter.cash_out', (model) => WithdrawPage(model)); // webview PageFactory.regist('pub.flutter.url', (model) => BaseWebview(model)); - PageFactory.regist( - 'pub.flutter.profile_settings', (model) => MineDetailPage()); + PageFactory.regist('pub.flutter.profile_settings', (model) => MineDetailPage()); PageFactory.regist('pub.flutter.settings', (model) => SettingPage(model)); PageFactory.regist('pub.flutter.my_order', (model) => OrdersPage(model)); - PageFactory.regist( - 'pub.flutter.account_security', (model) => SecurityPage(model)); - PageFactory.regist('pub.flutter.account_security_alipay', - (model) => SecurityBindAlipayPage(model)); + PageFactory.regist('pub.flutter.account_security', (model) => SecurityPage(model)); + PageFactory.regist('pub.flutter.account_security_alipay', (model) => SecurityBindAlipayPage(model)); // 登录密码 - PageFactory.regist('pub.flutter.account_security_password', - (model) => SecurityPassword(model)); + PageFactory.regist('pub.flutter.account_security_password', (model) => SecurityPassword(model)); // 修改手机号 - PageFactory.regist('pub.flutter.account_security_mobile', - (model) => SecurityMobile(model)); + PageFactory.regist('pub.flutter.account_security_mobile', (model) => SecurityMobile(model)); // 邀请好友 - PageFactory.regist( - 'pub.flutter.invite_friends', (model) => InvitedFriendsPage(model)); + PageFactory.regist('pub.flutter.invite_friends', (model) => InvitedFriendsPage(model)); /// 我的团队 PageFactory.regist('pub.flutter.my_team', (model) => TeamPage(model)); /// 用户详情 - PageFactory.regist( - 'pub.flutter.my_fan_detail', (model) => TeamDetailsPage(model)); + PageFactory.regist('pub.flutter.my_fan_detail', (model) => TeamDetailsPage(model)); /// 消息中心 - PageFactory.regist( - 'pub.flutter.message_center', (model) => MessageNoticePage(model)); + PageFactory.regist('pub.flutter.message_center', (model) => MessageNoticePage(model)); /// TODO 首页的消息中心标识和我的页面不一致,需要改 - PageFactory.regist( - 'pub.flutter.message', (model) => MessageNoticePage(model)); + PageFactory.regist('pub.flutter.message', (model) => MessageNoticePage(model)); /// 我的收藏 PageFactory.regist('pub.flutter.my_fav', (model) => FavoritesPage(model)); @@ -233,16 +212,13 @@ class BaseWidgetRegister { PageFactory.regist('pub.flutter.about_us', (model) => AboutUsPage(model)); /// 隐私设置 - PageFactory.regist( - 'pub.flutter.privacy_settings', (model) => PrivacySettingsPage(model)); + PageFactory.regist('pub.flutter.privacy_settings', (model) => PrivacySettingsPage(model)); /// 消息设置 - PageFactory.regist( - 'pub.flutter.message_settings', (model) => MessageSettingsPage(model)); + PageFactory.regist('pub.flutter.message_settings', (model) => MessageSettingsPage(model)); /// 钱包明细 - PageFactory.regist( - 'pub.flutter.my_wallet_detail', (model) => BilDetailPage(model)); + PageFactory.regist('pub.flutter.my_wallet_detail', (model) => BilDetailPage(model)); /// 通用模块 PageFactory.regist('pub.flutter.custom', (model) => CustomPage(model)); @@ -263,11 +239,12 @@ class BaseWidgetRegister { /// 可滚动banner WidgetFactory.regist('index_carousel', HomeSlideBannerCreater()); + /// 首页商品推荐列表 WidgetFactory.regist('index_recommend_list', GoodsListCreater()); /// 首页快速入口 - WidgetFactory.regist('multi_nav', DefaultWidgetCreater((model) => HomeQuickEntry(model))); + // WidgetFactory.regist('multi_nav', DefaultWidgetCreater((model) => HomeQuickEntry(model))); /// 滚动公告 WidgetFactory.regist('index_placard', DefaultWidgetCreater((model) => HomeNoticeWidget(model))); @@ -278,113 +255,82 @@ class BaseWidgetRegister { // WidgetFactory.regist('index_taobao_auth_tip', HomeAuthCreater()); /// ==================== 搜索页面 ==================== /// - // 搜索标题 - // WidgetFactory.regist('search_index_app_bar', DefaultWidgetCreater((model) => SearchAppbarWidget(model))); // 搜索输入框 - WidgetFactory.regist('search_index_input', - DefaultWidgetCreater((model) => SearchInputWidget(model))); + WidgetFactory.regist('search_index_input', DefaultWidgetCreater((model) => SearchInputWidget(model))); // // 搜索tabBar WidgetFactory.regist('search_index_icon_list', SearcchTabCreater()); - // WidgetFactory.regist('search_index_icon_list', DefaultWidgetCreater((model) => SearchTabWidget(model))); // // 热门搜索标签 - WidgetFactory.regist('search_index_host_keyword', - DefaultWidgetCreater((model) => SearchHotTagWidget(model))); + WidgetFactory.regist('search_index_hot_keyword', DefaultWidgetCreater((model) => SearchHotTagWidget(model))); // // 历史搜索标签 WidgetFactory.regist('search_index_history', DefaultWidgetCreater((model) => SearchHistoryTagWidget(model))); /// ==================== 搜索结果页面 ==================== /// // 输入框 - WidgetFactory.regist('search_result_input', - DefaultWidgetCreater((model) => SearchResultInputWidget(model))); + WidgetFactory.regist('search_result_input', DefaultWidgetCreater((model) => SearchResultInputWidget(model))); // tabbar WidgetFactory.regist('search_result_icon_list', SearchResultTabCreater()); + // 搜索筛选Widget + WidgetFactory.regist('search_conditions', DefaultWidgetCreater((model) => SearchResultSortWidget(model))); // 搜索结果页筛选widget 淘宝 - WidgetFactory.regist('search_result_taobao_sort', - DefaultWidgetCreater((model) => SearchResultSortWidget(model))); + WidgetFactory.regist('search_result_taobao_sort', DefaultWidgetCreater((model) => SearchResultSortWidget(model))); // 搜索结果的商品列表 淘宝 - WidgetFactory.regist( - 'search_result_taobao_item', SearchResultGoodsListCreater()); + WidgetFactory.regist('search_result_taobao_item', SearchResultGoodsListCreater()); // 搜索结果页筛选widget 京东 - WidgetFactory.regist('search_result_jd_sort', - DefaultWidgetCreater((model) => SearchResultSortWidget(model))); + WidgetFactory.regist('search_result_jd_sort', DefaultWidgetCreater((model) => SearchResultSortWidget(model))); // 搜索结果的商品列表 京东 - WidgetFactory.regist( - 'search_result_jd_item', SearchResultGoodsListCreater()); + WidgetFactory.regist('search_result_jd_item', SearchResultGoodsListCreater()); // 搜索结果页筛选widget 苏宁 - WidgetFactory.regist('search_result_suning_sort', - DefaultWidgetCreater((model) => SearchResultSortWidget(model))); + WidgetFactory.regist('search_result_suning_sort', DefaultWidgetCreater((model) => SearchResultSortWidget(model))); // 搜索结果的商品列表 苏宁 - WidgetFactory.regist( - 'search_result_suning_item', SearchResultGoodsListCreater()); + WidgetFactory.regist('search_result_suning_item', SearchResultGoodsListCreater()); // 搜索结果页筛选widget 拼多多 - WidgetFactory.regist('search_result_pdd_sort', - DefaultWidgetCreater((model) => SearchResultSortWidget(model))); + WidgetFactory.regist('search_result_pdd_sort', DefaultWidgetCreater((model) => SearchResultSortWidget(model))); // 搜索结果的商品列表 拼多多 - WidgetFactory.regist( - 'search_result_pdd_item', SearchResultGoodsListCreater()); + WidgetFactory.regist('search_result_pdd_item', SearchResultGoodsListCreater()); // 搜索结果页筛选widget 唯品会 - WidgetFactory.regist('search_result_vip_sort', - DefaultWidgetCreater((model) => SearchResultSortWidget(model))); + WidgetFactory.regist('search_result_vip_sort', DefaultWidgetCreater((model) => SearchResultSortWidget(model))); // 搜索结果的商品列表 唯品会 - WidgetFactory.regist( - 'search_result_vip_item', SearchResultGoodsListCreater()); + WidgetFactory.regist('search_result_vip_item', SearchResultGoodsListCreater()); // 搜索结果页筛选widget 考拉 - WidgetFactory.regist('search_result_kaola_sort', - DefaultWidgetCreater((model) => SearchResultSortWidget(model))); + WidgetFactory.regist('search_result_kaola_sort', DefaultWidgetCreater((model) => SearchResultSortWidget(model))); // 搜索结果的商品列表 考拉 - WidgetFactory.regist( - 'search_result_kaola_item', SearchResultGoodsListCreater()); + WidgetFactory.regist('search_result_kaola_item', SearchResultGoodsListCreater()); /// ==================== 商品详情 ==================== /// // 商品详情轮播图 - WidgetFactory.regist('product_detail_carousel', - DefaultWidgetCreater((model) => GoodsDetailsSlideBannerWidget(model))); + WidgetFactory.regist('product_detail_carousel', DefaultWidgetCreater((model) => GoodsDetailsSlideBannerWidget(model))); // 商品详情下载APP提示 - WidgetFactory.regist('product_detail_download_tips', - DefaultWidgetCreater((model) => UpgradeTipWidget(model))); + WidgetFactory.regist('product_detail_download_tips', DefaultWidgetCreater((model) => UpgradeTipWidget(model))); // 商品详情价格显示 - WidgetFactory.regist('product_detail_price', - DefaultWidgetCreater((model) => GoodsDetailsPriceWidget(model))); + WidgetFactory.regist('product_detail_price', DefaultWidgetCreater((model) => GoodsDetailsPriceWidget(model))); // 商品详情标题 - WidgetFactory.regist('product_detail_title', - DefaultWidgetCreater((model) => GoodsDetailsTitleWidget(model))); + WidgetFactory.regist('product_detail_title', DefaultWidgetCreater((model) => GoodsDetailsTitleWidget(model))); // 商品详情优惠劵 - WidgetFactory.regist('product_detail_coupon', - DefaultWidgetCreater((model) => CounponWidget(model))); + WidgetFactory.regist('product_detail_coupon', DefaultWidgetCreater((model) => CounponWidget(model))); // 商品详情店铺 - WidgetFactory.regist('product_detail_shop', - DefaultWidgetCreater((model) => StoreWidget(model))); + WidgetFactory.regist('product_detail_shop', DefaultWidgetCreater((model) => StoreWidget(model))); // 商品详情宝贝评价 - WidgetFactory.regist('product_detail_comment', - DefaultWidgetCreater((model) => GoodsDetailsEvaluateWidget(model))); + WidgetFactory.regist('product_detail_comment', DefaultWidgetCreater((model) => GoodsDetailsEvaluateWidget(model))); // 商品详情图片 - WidgetFactory.regist('product_detail_img_list', - DefaultWidgetCreater((model) => GoodsDetailsImgWidget(model))); + WidgetFactory.regist('product_detail_img_list', DefaultWidgetCreater((model) => GoodsDetailsImgWidget(model))); // 商品详情底部推荐列表 - WidgetFactory.regist( - 'product_detail_bottom_rec', GoodsDetailCommendCreater()); + WidgetFactory.regist('product_detail_bottom_rec', GoodsDetailCommendCreater()); // 商品详情底部 - WidgetFactory.regist('product_detail_bottom', - DefaultWidgetCreater((model) => GoodsDetailsFooterWidget(model))); + WidgetFactory.regist('product_detail_bottom', DefaultWidgetCreater((model) => GoodsDetailsFooterWidget(model))); // ==================== 个人中心 WidgetFactory.regist('profile_appbar', MineNavCreater()); - WidgetFactory.regist('profile_background', - DefaultWidgetCreater((model) => MineNavBg(model))); - WidgetFactory.regist( - 'profile_header', DefaultWidgetCreater((model) => MineHeader(model))); - WidgetFactory.regist( - 'profile_earning', DefaultWidgetCreater((model) => MineData(model))); - WidgetFactory.regist('profile_functions', - DefaultWidgetCreater((model) => MineQuickEntry(model))); - WidgetFactory.regist('profile_my_functions', - DefaultWidgetCreater((model) => MineQuickEntry(model))); + WidgetFactory.regist('profile_background', DefaultWidgetCreater((model) => MineNavBg(model))); + WidgetFactory.regist('profile_header', DefaultWidgetCreater((model) => MineHeader(model))); + WidgetFactory.regist('profile_earning', DefaultWidgetCreater((model) => MineData(model))); + WidgetFactory.regist('profile_functions', DefaultWidgetCreater((model) => MineQuickEntry(model))); + WidgetFactory.regist('profile_my_functions', DefaultWidgetCreater((model) => MineQuickEntry(model))); // WidgetFactory.regist('profile_carousel', DefaultWidgetCreater((model) => HomeBannerWidget(model))); // WidgetFactory.regist('profile_carousel', HomeBannerCreater()); @@ -396,18 +342,14 @@ class BaseWidgetRegister { // ))); WidgetFactory.regist('my_wallet_appbar', NormalNavCreater()); - WidgetFactory.regist( - 'my_wallet_header', DefaultWidgetCreater((model) => WalletData(model))); - WidgetFactory.regist( - 'my_wallet_bil', DefaultWidgetCreater((model) => WalletBil(model))); + WidgetFactory.regist('my_wallet_header', DefaultWidgetCreater((model) => WalletData(model))); + WidgetFactory.regist('my_wallet_bil', DefaultWidgetCreater((model) => WalletBil(model))); // WidgetFactory.regist( // 'wallet_detail', DefaultWidgetCreater((model) => WalletDetail())); // WidgetFactory.regist('wallet_detail', HomeAuthCreater()); - WidgetFactory.regist('my_wallet_providers', - DefaultWidgetCreater((model) => WalletDetail(model))); + WidgetFactory.regist('my_wallet_providers', DefaultWidgetCreater((model) => WalletDetail(model))); - WidgetFactory.regist( - 'wallet_income', DefaultWidgetCreater((model) => WalletIncome())); + WidgetFactory.regist('wallet_income', DefaultWidgetCreater((model) => WalletIncome())); //======================= 账单明细 WidgetFactory.regist( @@ -417,22 +359,20 @@ class BaseWidgetRegister { ))); //======================== 热榜 - WidgetFactory.regist('hot_rank_appbar', - DefaultWidgetCreater((model) => HotRankingAppBar(model))); - WidgetFactory.regist('hot_rank_tabs', - DefaultWidgetCreater((model) => HotRankTableBar(model))); - WidgetFactory.regist('hot_rank_tab_view', - DefaultWidgetCreater((model) => HotRankingList(model))); - + WidgetFactory.regist('hot_rank_appbar', DefaultWidgetCreater((model) => HotRankingAppBar(model))); + WidgetFactory.regist('hot_rank_tabs', DefaultWidgetCreater((model) => HotRankTableBar(model))); + WidgetFactory.regist('hot_rank_tab_view', DefaultWidgetCreater((model) => HotRankingList(model))); /// ==================== 通用模块 ==================== /// // 搜索 - WidgetFactory.regist('search_test', DefaultWidgetCreater((model) => CustomSearchWidget(model))); + WidgetFactory.regist('search', DefaultWidgetCreater((model) => CustomSearchWidget(model))); // 轮播广告位, 可滑动 - WidgetFactory.regist('carousel_test', CustomSlideBannerCreater()); + WidgetFactory.regist('carousel', CustomSlideBannerCreater()); // 多眼导航,可滑动 - WidgetFactory.regist('multi_nav_test', DefaultWidgetCreater((model) => CustomQuickEntry(model))); + WidgetFactory.regist('multi_nav', DefaultWidgetCreater((model) => CustomQuickEntry(model))); + // banner, 不可滑动 + WidgetFactory.regist('banner', DefaultWidgetCreater((model) => CustomBannerWidget(model))); // 商品列表 - WidgetFactory.regist('product_test', GoodsDetailCommendCreater()); + WidgetFactory.regist('product', CustomGoodsCreater()); } } diff --git a/lib/widgets/custom/banner/custom_banner_widget.dart b/lib/widgets/custom/banner/custom_banner_widget.dart new file mode 100644 index 0000000..81c00a4 --- /dev/null +++ b/lib/widgets/custom/banner/custom_banner_widget.dart @@ -0,0 +1,210 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:zhiying_base_widget/widgets/custom/banner/model/custom_banner_model.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +/// +/// 通用的BannerWidget +/// +class CustomBannerWidget extends StatelessWidget { + final Map data; + CustomBannerModel _model; + + CustomBannerWidget(this.data, {Key key}) : super(key: key) { + try { + _model = CustomBannerModel.fromJson(jsonDecode(data['data'])); + } catch (e, s) { + Logger.warn(e, s); + } + } + + /// 点击事件 + void _itemOnClick(BuildContext context, CustomBannerListStyle model) { + print('${model?.skipIdentifier}'); + RouterUtil.route(model, model.toJson(), context); + } + + double _convert(String val) { + double result = 0.0; + try { + result = double.parse(val); + } catch (e) { + result = 0; + } + return result; + } + + @override + Widget build(BuildContext context) { + /// 空视图 + if (EmptyUtil.isEmpty(_model)) { + return Container(); + } + + return Container( + width: double.infinity, + height: 90, + // color: Colors.red, + padding: EdgeInsets.only(top: _convert(_model?.topMargin), left: 12.5, right: 12.5), + child: _buildMainWidget(context, _model?.moduleType, _model?.listStyle), + ); + } + + /// 主视图 + Widget _buildMainWidget(BuildContext context, String moduleType, List listStyle) { + if (EmptyUtil.isEmpty(listStyle)) return Container(); + Widget rlt; + switch (moduleType) { + case 'banner1': + rlt = _buildStyle1(context, listStyle); + break; + case 'banner2': + rlt = _buildStyle2(context, listStyle); + break; + case 'banner3': + rlt = _buildStyle3(context, listStyle); + break; + case 'banner4': + rlt = _buildStyle4(context, listStyle); + break; + case 'banner5': + rlt = _buildStyle5(context, listStyle); + break; + case 'banner6': + rlt = _buildStyle6(context, listStyle); + break; + case 'banner7': + rlt = _buildStyle7(context, listStyle); + break; + case 'banner8': + rlt = _buildStyle8(context, listStyle); + break; + default: + rlt = Container(); + break; + } + return rlt; + } + + /// 1张图 + Widget _buildStyle1(BuildContext context, List listStyle) { + return _buildColumnWidget(context, listStyle); + } + + /// 左1右1 + Widget _buildStyle2(BuildContext context, List listStyle) { + return _buildColumnWidget(context, listStyle); + } + + /// 左1右2 + Widget _buildStyle3(BuildContext context, List listStyle) { + CustomBannerListStyle left1 = listStyle.firstWhere((element) => element.locationType == 'left1'); + CustomBannerListStyle right1 = listStyle.firstWhere((element) => element.locationType == 'right1'); + CustomBannerListStyle right2 = listStyle.firstWhere((element) => element.locationType == 'right2'); + if (EmptyUtil.isEmpty(left1) || EmptyUtil.isEmpty(right1) || EmptyUtil.isEmpty(right2)) return Container(); + return Row( + children: [ + Flexible(flex: 1, child: GestureDetector(onTap: () => _itemOnClick(context, left1), child: CachedNetworkImage(imageUrl: left1?.img ?? ''))), + Flexible( + flex: 1, + child: Column( + children: [ + Flexible(flex: 1, child: GestureDetector(onTap: () => _itemOnClick(context, right1), child: CachedNetworkImage(imageUrl: right1?.img ?? ''))), + Flexible(flex: 1, child: GestureDetector(onTap: () => _itemOnClick(context, right2), child: CachedNetworkImage(imageUrl: right2?.img ?? ''))), + ], + ), + ), + ], + ); + } + + /// 左2右1 + Widget _buildStyle4(BuildContext context, List listStyle) { + CustomBannerListStyle left1 = listStyle.firstWhere((element) => element.locationType == 'left1'); + CustomBannerListStyle left2 = listStyle.firstWhere((element) => element.locationType == 'left2'); + CustomBannerListStyle right1 = listStyle.firstWhere((element) => element.locationType == 'right1'); + if (EmptyUtil.isEmpty(left1) || EmptyUtil.isEmpty(right1) || EmptyUtil.isEmpty(left2)) return Container(); + return Row( + children: [ + Flexible( + flex: 1, + child: Column( + children: [ + Flexible(flex: 1, child: GestureDetector(onTap: () => _itemOnClick(context, left1), child: CachedNetworkImage(imageUrl: left1?.img ?? ''))), + Flexible(flex: 1, child: GestureDetector(onTap: () => _itemOnClick(context, left2), child: CachedNetworkImage(imageUrl: left2?.img ?? ''))), + ], + ), + ), + Flexible(flex: 1, child: GestureDetector(onTap: () => _itemOnClick(context, right1), child: CachedNetworkImage(imageUrl: right1?.img ?? ''))), + ], + ); + } + + /// 左1右3 + Widget _buildStyle5(BuildContext context, List listStyle) { + CustomBannerListStyle left1 = listStyle.firstWhere((element) => element.locationType == 'left1'); + CustomBannerListStyle right1 = listStyle.firstWhere((element) => element.locationType == 'right1'); + CustomBannerListStyle right2 = listStyle.firstWhere((element) => element.locationType == 'right2'); + CustomBannerListStyle right3 = listStyle.firstWhere((element) => element.locationType == 'right3'); + if (EmptyUtil.isEmpty(left1) || EmptyUtil.isEmpty(right1) || EmptyUtil.isEmpty(right2) || EmptyUtil.isEmpty(right3)) return Container(); + + return Row( + children: [ + Flexible(flex: 4, child: GestureDetector(onTap: () => _itemOnClick(context, left1), child: CachedNetworkImage(imageUrl: left1?.img ?? ''))), + Flexible( + flex: 6, + child: Column( + children: [ + Flexible(flex: 1, child: GestureDetector(onTap: () => _itemOnClick(context, right1), child: CachedNetworkImage(imageUrl: right1?.img ?? ''))), + Row( + children: [ + Flexible(flex: 1, child: GestureDetector(onTap: () => _itemOnClick(context, right2), child: CachedNetworkImage(imageUrl: right2?.img ?? ''))), + Flexible(flex: 1, child: GestureDetector(onTap: () => _itemOnClick(context, right3), child: CachedNetworkImage(imageUrl: right3?.img ?? ''))), + ], + ) + ], + ), + ) + ], + ); + } + + /// 3列 + Widget _buildStyle6(BuildContext context, List listStyle) { + return _buildColumnWidget(context, listStyle); + } + + /// 4列 + Widget _buildStyle7(BuildContext context, List listStyle) { + return _buildColumnWidget(context, listStyle); + } + + /// 5列 + Widget _buildStyle8(BuildContext context, List listStyle) { + return _buildColumnWidget(context, listStyle); + } + + /// 列的通用 + Widget _buildColumnWidget(BuildContext context, List listStyle) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: listStyle + .map((e) => Flexible( + flex: 1, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => _itemOnClick(context, e), + child: Container( + height: double.infinity, + width: double.infinity, + child: CachedNetworkImage( + imageUrl: e?.img ?? '', + fit: BoxFit.fitWidth, + )), + ), + )) + .toList(), + ); + } +} diff --git a/lib/widgets/custom/banner/model/custom_banner_model.dart b/lib/widgets/custom/banner/model/custom_banner_model.dart new file mode 100644 index 0000000..edd552e --- /dev/null +++ b/lib/widgets/custom/banner/model/custom_banner_model.dart @@ -0,0 +1,92 @@ +import 'package:zhiying_base_widget/dialog/global_dialog/intellect_search_goods_dialog/model/no_goods_dialog_style_model.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class CustomBannerModel { + String name; + String desc; + String moduleType; + String moduleKey; + String isTopMargin; + String isLeftRightMargin; + String isShow; + String topMargin; + String leftRightMargin; + List listStyle; + int moduleKeyId; + + CustomBannerModel( + {this.name, this.desc, this.moduleType, this.moduleKey, this.isTopMargin, this.isLeftRightMargin, this.isShow, this.topMargin, this.leftRightMargin, this.listStyle, this.moduleKeyId}); + + CustomBannerModel.fromJson(Map json) { + name = json['name']; + desc = json['desc']; + moduleType = json['module_type']; + moduleKey = json['module_key']; + isTopMargin = json['is_top_margin']; + isLeftRightMargin = json['is_left_right_margin']; + isShow = json['is_show']; + topMargin = json['top_margin']; + leftRightMargin = json['left_right_margin']; + if (json['list_style'] != null) { + listStyle = new List(); + json['list_style'].forEach((v) { + listStyle.add(new CustomBannerListStyle.fromJson(v)); + }); + } + moduleKeyId = json['module_key_id']; + } + + Map toJson() { + final Map data = new Map(); + data['name'] = this.name; + data['desc'] = this.desc; + data['module_type'] = this.moduleType; + data['module_key'] = this.moduleKey; + data['is_top_margin'] = this.isTopMargin; + data['is_left_right_margin'] = this.isLeftRightMargin; + data['is_show'] = this.isShow; + data['top_margin'] = this.topMargin; + data['left_right_margin'] = this.leftRightMargin; + if (this.listStyle != null) { + data['list_style'] = this.listStyle.map((v) => v.toJson()).toList(); + } + data['module_key_id'] = this.moduleKeyId; + return data; + } +} + +class CustomBannerListStyle extends SkipModel{ + String name; + String img; + String locationType; + String locationName; + String requiredLogin; + String requiredTaobaoAuth; + String skipIdentifier; + + CustomBannerListStyle({this.name, this.img, this.locationType, this.locationName, this.requiredLogin, this.requiredTaobaoAuth, this.skipIdentifier}); + + CustomBannerListStyle.fromJson(Map json) { + super.fromJson(json); + name = json['name']; + img = json['img']; + locationType = json['location_type']; + locationName = json['location_name']; + requiredLogin = json['required_login']; + requiredTaobaoAuth = json['required_taobao_auth']; + skipIdentifier = json['skip_identifier']; + } + + Map toJson() { + final Map data = super.toJson(); + + data['name'] = this.name; + data['img'] = this.img; + data['location_type'] = this.locationType; + data['location_name'] = this.locationName; + data['required_login'] = this.requiredLogin; + data['required_taobao_auth'] = this.requiredTaobaoAuth; + data['skip_identifier'] = this.skipIdentifier; + return data; + } +} diff --git a/lib/widgets/custom/goods/custom_goods_widget.dart b/lib/widgets/custom/goods/custom_goods_widget.dart new file mode 100644 index 0000000..26c35b9 --- /dev/null +++ b/lib/widgets/custom/goods/custom_goods_widget.dart @@ -0,0 +1,28 @@ +import 'dart:convert'; +import 'package:flutter/cupertino.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/recommend/goods_detail_commend_creater.dart'; +import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +/// +/// 通用模块的商品列表 +/// +class CustomGoodsCreater extends WidgetCreater { + WidgetCreater creater; + + @override + List createWidgets(Map model) { + Map json = jsonDecode(model['data']); + if (!EmptyUtil.isEmpty(json['recommend_list'])) { + creater = GoodsListCreater(); + } else { + creater = GoodsDetailCommendCreater(); + } + return creater?.createWidgets(model) ?? SliverToBoxAdapter(child: Container()); + } + + @override + bool isSliverChild() { + return creater?.isSliverChild() ?? true; + } +} diff --git a/lib/widgets/custom/multi_nav/custom_quick_entry.dart b/lib/widgets/custom/multi_nav/custom_quick_entry.dart index 94e6ec8..cdc98a5 100644 --- a/lib/widgets/custom/multi_nav/custom_quick_entry.dart +++ b/lib/widgets/custom/multi_nav/custom_quick_entry.dart @@ -115,6 +115,7 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> return Container( color: HexColor.fromHex(widget?.model['bg_color']), + // color: Colors.yellow, child: Container( margin: EdgeInsets.only(top: 15, bottom: totalPage > 1 ? 15 : 0), height: totalHeight, diff --git a/lib/widgets/custom/search/custom_search_widget.dart b/lib/widgets/custom/search/custom_search_widget.dart index 3dfcd90..65a638f 100644 --- a/lib/widgets/custom/search/custom_search_widget.dart +++ b/lib/widgets/custom/search/custom_search_widget.dart @@ -21,23 +21,85 @@ class CustomSearchWidget extends StatelessWidget { // 点击事件 void _onClickListener(BuildContext context, SkipModel skipModel) { - RouterUtil.route(skipModel, skipModel.toJson(), context); + if (!EmptyUtil.isEmpty(skipModel)) { + RouterUtil.route(skipModel, skipModel.toJson(), context); + } } @override Widget build(BuildContext context) { - return _buildStyle1Widget(context); + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: HexColor.fromHex(model?.bgColor), + ), + padding: const EdgeInsets.symmetric(horizontal: 12.5, vertical: 4), + child: _buildMainWidget(context)); } - /// 样式1 + Widget _buildMainWidget(BuildContext context) { + if (EmptyUtil.isEmpty(model)) return Container(); + Widget rlt; + switch (model.moduleType) { + case 'search_1': + rlt = _buildStyle1Widget(context); + break; + case 'search_2': + rlt = _buildStyle2Widget(context); + break; + default: + rlt = Container(); + break; + } + + return rlt; + } + + /// 右1图标 Widget _buildStyle1Widget(BuildContext context) { + return Row( + children: [ + Expanded( + child: GestureDetector( + onTap: () => _onClickListener(context, model?.listStyle?.searchCss), + behavior: HitTestBehavior.opaque, + child: Container( + // height: 30, + width: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 9), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(60 / 2), color: HexColor.fromHex(model?.listStyle?.searchCss?.bgColor)), + child: Row( + children: [ + CachedNetworkImage( + width: 13, + height: 13, + imageUrl: model?.listStyle?.searchCss?.image ?? '', + ), + SizedBox(width: 4), + Text(model?.listStyle?.searchCss?.text ?? '输入搜索内容,领券省钱', style: TextStyle(fontSize: 13, color: HexColor.fromHex('#FFFFFFFF'))) + ], + ), + ), + )), + SizedBox(width: 10), + GestureDetector( + onTap: () => _onClickListener(context, model?.listStyle?.rightCss), + child: CachedNetworkImage( + width: 30, + height: 30, + imageUrl: model?.listStyle?.rightCss?.image ?? '', + )), + ], + ); + } + + /// 无图标 + Widget _buildStyle2Widget(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => _onClickListener(context, model?.listStyle?.searchCss), child: Container( width: double.infinity, - decoration: BoxDecoration(color: HexColor.fromHex(model?.bgColor ?? '#FFFFFF')), - padding: const EdgeInsets.symmetric(horizontal: 12.5, vertical: 4), child: Container( width: double.infinity, decoration: BoxDecoration( diff --git a/lib/widgets/custom/slide_banner/custom_slide_banner.dart b/lib/widgets/custom/slide_banner/custom_slide_banner.dart index 60d2488..a532a6e 100644 --- a/lib/widgets/custom/slide_banner/custom_slide_banner.dart +++ b/lib/widgets/custom/slide_banner/custom_slide_banner.dart @@ -104,6 +104,7 @@ class _CustomSlideBannerContainerState extends State margin: EdgeInsets.all(10), width: double.infinity, height: 140, + // color: Colors.green, child: Swiper( controller: _swiperController, itemBuilder: (BuildContext context, int index) { diff --git a/lib/widgets/goods_details/title/goods_details_title_widget.dart b/lib/widgets/goods_details/title/goods_details_title_widget.dart index 47083c3..94bd1dc 100644 --- a/lib/widgets/goods_details/title/goods_details_title_widget.dart +++ b/lib/widgets/goods_details/title/goods_details_title_widget.dart @@ -32,17 +32,18 @@ class GoodsDetailsTitleWidget extends StatelessWidget { /// 主widget Widget _getMaiWidget(GoodsDetailsTitleModel model) { return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, children: [ RichText( maxLines: 2, overflow: TextOverflow.ellipsis, text: TextSpan(children: [ - WidgetSpan( - child: _getGoodsTypeIcon(model), - ), + WidgetSpan(child: _getGoodsTypeIcon(model)), _getGoodsTitle(model), ]), ), + /// 优惠卷说明 Padding(padding: const EdgeInsets.only(top: 12.5), child: _getCounponDestrWidget(model)), ], @@ -57,14 +58,14 @@ class GoodsDetailsTitleWidget extends StatelessWidget { padding: const EdgeInsets.only(left: 7.5, right: 7.5, bottom: 2, top: 3), margin: const EdgeInsets.only(right: 4), decoration: BoxDecoration(borderRadius: BorderRadius.circular(2.5), color: HexColor.fromHex(model?.provider_bg_color)), - child: Text(model?.provider_name, style: TextStyle(color: HexColor.fromHex(model?.provider_name_color), fontSize: 9)), + child: Text(model?.provider_name, textAlign: TextAlign.center, style: TextStyle(color: HexColor.fromHex(model?.provider_name_color), fontSize: 9)), ); } /// 商品标题 InlineSpan _getGoodsTitle(GoodsDetailsTitleModel model) { return TextSpan( - text: model?.title ?? '品胜(PISEN)苹果数据线1.5米 适用于苹果手机所有机型 MFI认证安全稳定一年换新1.5米2米', + text: model?.title ?? '', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 14, @@ -78,17 +79,17 @@ class GoodsDetailsTitleWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ /// 领券立减100元 widget - _getCoumstonButtomWidget(model?.coupon_text, model?.coupon_text_color, model?.coupon_bg_color), - const SizedBox(width: 5), + Visibility(visible: !EmptyUtil.isEmpty(model?.couponPrice), child: _getCoumstonButtomWidget(model?.coupon_text, model?.coupon_text_color, model?.coupon_bg_color)), /// 收货后返现5.5元 - _getCoumstonButtomWidget(model?.commission_text, model?.commission_text_color, model?.commission_bg_color), + Visibility(visible: !EmptyUtil.isEmpty(model?.commission), child: _getCoumstonButtomWidget(model?.commission_text, model?.commission_text_color, model?.commission_bg_color)), ], ); } Widget _getCoumstonButtomWidget(String text, String textColor, String bg) { return Container( + margin: const EdgeInsets.only(right: 5), padding: const EdgeInsets.only(left: 13.5, right: 14.5, top: 2.5, bottom: 2.5), decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: HexColor.fromHex(bg)), child: Text( diff --git a/lib/widgets/goods_details/title/model/goods_details_title_model.dart b/lib/widgets/goods_details/title/model/goods_details_title_model.dart index f06e357..bb5b5cf 100644 --- a/lib/widgets/goods_details/title/model/goods_details_title_model.dart +++ b/lib/widgets/goods_details/title/model/goods_details_title_model.dart @@ -10,19 +10,24 @@ class GoodsDetailsTitleModel { String provider_name; String provider_name_color; String title; + String commission; + String couponPrice; - GoodsDetailsTitleModel( - {this.commission_bg_color, - this.commission_text, - this.commission_text_color, - this.coupon_bg_color, - this.coupon_text, - this.coupon_text_color, - this.good_title_color, - this.provider_bg_color, - this.provider_name, - this.provider_name_color, - this.title}); + GoodsDetailsTitleModel({ + this.commission_bg_color, + this.commission_text, + this.commission_text_color, + this.coupon_bg_color, + this.coupon_text, + this.coupon_text_color, + this.good_title_color, + this.provider_bg_color, + this.provider_name, + this.provider_name_color, + this.title, + this.commission, + this.couponPrice, + }); factory GoodsDetailsTitleModel.fromJson(Map json) { return GoodsDetailsTitleModel( @@ -37,6 +42,8 @@ class GoodsDetailsTitleModel { provider_name: json['provider_name'], provider_name_color: json['provider_name_color'], title: json['title'], + commission: json['commission'], + couponPrice: json['coupon_price'], ); } @@ -53,6 +60,8 @@ class GoodsDetailsTitleModel { data['provider_name'] = this.provider_name; data['provider_name_color'] = this.provider_name_color; data['title'] = this.title; + data['coupon_price'] = this.couponPrice; + data['commission'] = this.commission; return data; } } diff --git a/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart b/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart index 20bc502..81473db 100644 --- a/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart +++ b/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart @@ -1,36 +1,44 @@ +import 'package:zhiying_comm/zhiying_comm.dart'; -class UpgradeTipModel { - String bg_color; - String go_text; - String go_text_color; - String icon; - String text; - String text_color; - String url; +class UpgradeTipModel extends SkipModel { + String bg_color; + String go_text; + String go_text_color; + String icon; + String text; + String text_color; + String url; - UpgradeTipModel({this.bg_color, this.go_text, this.go_text_color, this.icon, this.text, this.text_color, this.url}); + UpgradeTipModel({ + this.bg_color, + this.go_text, + this.go_text_color, + this.icon, + this.text, + this.text_color, + this.url, + }); - factory UpgradeTipModel.fromJson(Map json) { - return UpgradeTipModel( - bg_color: json['bg_color'], - go_text: json['go_text'], - go_text_color: json['go_text_color'], - icon: json['icon'], - text: json['text'], - text_color: json['text_color'], - url: json['url'], - ); - } + UpgradeTipModel.fromJson(Map json) { + super.fromJson(json); + bg_color = json['bg_color']; + go_text = json['go_text']; + go_text_color = json['go_text_color']; + icon = json['icon']; + text = json['text']; + text_color = json['text_color']; + url = json['url']; + } - Map toJson() { - final Map data = new Map(); - data['bg_color'] = this.bg_color; - data['go_text'] = this.go_text; - data['go_text_color'] = this.go_text_color; - data['icon'] = this.icon; - data['text'] = this.text; - data['text_color'] = this.text_color; - data['url'] = this.url; - return data; - } -} \ No newline at end of file + Map toJson() { + final Map data = super.toJson(); + data['bg_color'] = this.bg_color; + data['go_text'] = this.go_text; + data['go_text_color'] = this.go_text_color; + data['icon'] = this.icon; + data['text'] = this.text; + data['text_color'] = this.text_color; + data['url'] = this.url; + return data; + } +} diff --git a/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart b/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart index 48897b6..aa6049d 100644 --- a/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart +++ b/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart @@ -11,36 +11,44 @@ import 'package:cached_network_image/cached_network_image.dart'; class UpgradeTipWidget extends StatelessWidget { final Map model; UpgradeTipModel _upgradeTipModel; - UpgradeTipWidget(this.model, {Key key}) : super(key: key){ - try{ + + UpgradeTipWidget(this.model, {Key key}) : super(key: key) { + try { _upgradeTipModel = UpgradeTipModel.fromJson(jsonDecode(model['data'])); - }catch(e){ + } catch (e) { Logger.log('UpgradeTipWidget e = $e'); } } + void _onClickListener(context) { + if (!EmptyUtil.isEmpty(_upgradeTipModel)) { + RouterUtil.route(_upgradeTipModel, _upgradeTipModel.toJson(), context); + } + } + @override Widget build(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 12.5), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only(topLeft: Radius.circular(7.5), topRight: Radius.circular(7.5)) - ), - child: Container( - decoration: BoxDecoration( - /// 背景颜色 - color: HexColor.fromHex(_upgradeTipModel?.bg_color ?? '#FFEFDA'), - borderRadius: BorderRadius.circular(30), - ), - padding: const EdgeInsets.only(left: 10, right: 13, top: 10, bottom: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - _geLeftWidget(_upgradeTipModel), - _getRightWidget(_upgradeTipModel), - ], + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.only(topLeft: Radius.circular(7.5), topRight: Radius.circular(7.5))), + child: GestureDetector( + onTap: () => _onClickListener(context), + behavior: HitTestBehavior.opaque, + child: Container( + decoration: BoxDecoration( + /// 背景颜色 + color: HexColor.fromHex(_upgradeTipModel?.bg_color ?? '#FFEFDA'), + borderRadius: BorderRadius.circular(30), + ), + padding: const EdgeInsets.only(left: 10, right: 13, top: 10, bottom: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _geLeftWidget(_upgradeTipModel), + _getRightWidget(_upgradeTipModel), + ], + ), ), ), ); @@ -52,19 +60,22 @@ class UpgradeTipWidget extends StatelessWidget { children: [ /// 图标 // Container(width: 15, height: 15, child: ,), - CachedNetworkImage(imageUrl: model?.icon ?? '', width: 15,), + CachedNetworkImage( + imageUrl: model?.icon ?? '', + width: 15, + ), const SizedBox(width: 7.5), /// 文字 - Text(model?.text ?? '下载APP升级运营商,享受更多收益', style: TextStyle(color: HexColor.fromHex( model?.text_color ?? '#C09023'), fontSize: 11)) + Text(model?.text ?? '下载APP升级运营商,享受更多收益', style: TextStyle(color: HexColor.fromHex(model?.text_color ?? '#C09023'), fontSize: 11)) ], ); } /// 右边的视图 Widget _getRightWidget(UpgradeTipModel model) { - return Text(model?.go_text ??'前往下载', style: TextStyle(color: HexColor.fromHex(model?.go_text_color ?? '#C09023'), fontSize: 11)); + return Text(model?.go_text ?? '前往下载', style: TextStyle(color: HexColor.fromHex(model?.go_text_color ?? '#C09023'), fontSize: 11)); // return Row( // children: [ // Text(model?.go_text ??'前往下载', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11)), diff --git a/lib/widgets/home/home_goods/home_goods.dart b/lib/widgets/home/home_goods/home_goods.dart index 42e10da..0e5e2dc 100644 --- a/lib/widgets/home/home_goods/home_goods.dart +++ b/lib/widgets/home/home_goods/home_goods.dart @@ -64,10 +64,10 @@ class _HomeGoodsContainerState extends State<_HomeGoodsContainer> { _style = HomeGoodsStyleModel.fromJson(Map.from(json)); widget.eventBus.on().listen((data) { - if (!_isFirstLoading) { - // 老板说打开app的时候,第一次加载不要显示loading - Loading.show(context); - } + // if (!_isFirstLoading) { + // // 老板说打开app的时候,第一次加载不要显示loading + // Loading.show(context); + // } _isFirstLoading = false; _provider = data.provider; _bloc.loadMore(_provider); @@ -97,7 +97,7 @@ class _HomeGoodsContainerState extends State<_HomeGoodsContainer> { // child: HomeGoodsSkeleton(), // ); // } - Loading.dismiss(); + // Loading.dismiss(); List goods = snapshot.data; int column = int.tryParse(_style.listColumn ?? '1'); column = column <= 0 ? 1 : column;