@@ -55,7 +55,11 @@ class CustomPageBloc extends Bloc<CustomPageEvent, CustomPageState> { | |||||
if (!EmptyUtil.isEmpty(result) && result is List) { | if (!EmptyUtil.isEmpty(result) && result is List) { | ||||
yield CustomPageLoadedState(model: result); | yield CustomPageLoadedState(model: result); | ||||
} else { | } else { | ||||
yield CustomPageInitErrorState(); | |||||
if(EmptyUtil.isEmpty(cache)) { | |||||
yield CustomPageInitErrorState(); | |||||
}else{ | |||||
yield CustomPageErrorState(); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -1,10 +1,13 @@ | |||||
import 'package:event_bus/event_bus.dart'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:pull_to_refresh/pull_to_refresh.dart'; | import 'package:pull_to_refresh/pull_to_refresh.dart'; | ||||
import 'package:provider/provider.dart'; | import 'package:provider/provider.dart'; | ||||
import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart'; | import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart'; | ||||
import 'package:zhiying_base_widget/widgets/empty/empty_widget.dart'; | import 'package:zhiying_base_widget/widgets/empty/empty_widget.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_auth/home_auth.dart'; | |||||
import 'package:zhiying_base_widget/widgets/refresh/refresh_footer/refresh_footer.dart'; | import 'package:zhiying_base_widget/widgets/refresh/refresh_footer/refresh_footer.dart'; | ||||
import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_gif_header.dart'; | |||||
import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_header.dart'; | import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_header.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'bloc/custom_item_page_bloc.dart'; | import 'bloc/custom_item_page_bloc.dart'; | ||||
@@ -60,6 +63,8 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit | |||||
ScrollController _controller; | ScrollController _controller; | ||||
RefreshController _refreshController; | RefreshController _refreshController; | ||||
final EventBus _eventBus = EventBus(); | |||||
/// 回到顶点 | /// 回到顶点 | ||||
void _scrollTop() { | void _scrollTop() { | ||||
@@ -145,18 +150,26 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit | |||||
return MediaQuery.removePadding( | return MediaQuery.removePadding( | ||||
context: context, | context: context, | ||||
removeTop: false, | removeTop: false, | ||||
child: SmartRefresher( | |||||
controller: _refreshController, | |||||
enablePullDown: true, | |||||
enablePullUp: true, | |||||
onRefresh: _refreshEvent, | |||||
onLoading: _loadEvent, | |||||
header: RefreshHeader(), | |||||
// footer: RefreshFooter(), | |||||
child: CustomScrollView( | |||||
controller: _controller, | |||||
slivers: _buildContentWidgets(model), | |||||
), | |||||
child: Stack( | |||||
children: <Widget>[ | |||||
SmartRefresher( | |||||
controller: _refreshController, | |||||
enablePullDown: true, | |||||
enablePullUp: true, | |||||
onRefresh: _refreshEvent, | |||||
onLoading: _loadEvent, | |||||
header: RefreshGifHeader(), | |||||
// footer: RefreshFooter(), | |||||
child: CustomScrollView( | |||||
controller: _controller, | |||||
slivers: _buildContentWidgets(model), | |||||
), | |||||
), | |||||
Align( | |||||
alignment: Alignment.bottomCenter, | |||||
child: Container( margin: const EdgeInsets.only(bottom: 8), child: _buildAuthWidget(model),), //_buildAuthWidget(model), | |||||
) | |||||
], | |||||
), | ), | ||||
); | ); | ||||
} | } | ||||
@@ -166,6 +179,13 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit | |||||
List<Widget> result = []; | List<Widget> result = []; | ||||
for (int i = 0; i < datas.length; i++) { | for (int i = 0; i < datas.length; i++) { | ||||
WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(datas[i])); | WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(datas[i])); | ||||
if(item.modName == 'audit_tip'){ | |||||
Logger.debug('授权组件,跳过'); | |||||
continue; | |||||
} | |||||
if(item.modName == 'product'){ | |||||
datas[i]['eventBus'] = _eventBus; | |||||
} | |||||
result.addAll(WidgetFactory.create( | result.addAll(WidgetFactory.create( | ||||
item.modName, | item.modName, | ||||
isSliver: true, | isSliver: true, | ||||
@@ -173,20 +193,20 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit | |||||
)); | )); | ||||
} | } | ||||
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'), | |||||
)), | |||||
)); | |||||
} | |||||
// if (widget.needBuildStatus) { | |||||
// double top = MediaQueryData.fromWindow(window).padding.top; | |||||
// result.insert( | |||||
// 0, | |||||
// SliverPersistentHeader( | |||||
// pinned: false, | |||||
// floating: false, | |||||
// delegate: CustomSliverPersistentHeaderDelegate(max: top, min: top, child: Container( | |||||
// // color: Colors.yellow, | |||||
// color: HexColor.fromHex('#FFFF4242'), | |||||
// )), | |||||
// )); | |||||
// | |||||
// } | |||||
return result; | return result; | ||||
} | } | ||||
@@ -207,4 +227,22 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit | |||||
Widget _buildSkeletonWidget() { | Widget _buildSkeletonWidget() { | ||||
return Container(); | return Container(); | ||||
} | } | ||||
/// 特殊的授权组件 | |||||
Widget _buildAuthWidget(final List<Map<String, dynamic>> datas){ | |||||
int length = datas?.length ?? 0; | |||||
if(length == 0) return Container(); | |||||
Widget rlt; | |||||
for (int i = 0; i < datas.length; i++) { | |||||
WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(datas[i])); | |||||
if(item.modName == 'audit_tip'){ | |||||
rlt = HomeAuth(datas[i]); | |||||
break; | |||||
} | |||||
} | |||||
return rlt ?? Container(); | |||||
} | |||||
} | } |
@@ -119,29 +119,9 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single | |||||
Widget _buildMainWidget(List<Map<String, dynamic>> model) { | Widget _buildMainWidget(List<Map<String, dynamic>> model) { | ||||
return Stack( | return Stack( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
// 背景 | |||||
Column( | |||||
children: <Widget>[ | |||||
// 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( | Scaffold( | ||||
appBar: _buildAppbar(model?.first), | appBar: _buildAppbar(model?.first), | ||||
backgroundColor: Colors.transparent, | |||||
backgroundColor: HexColor.fromHex('#F9F9F9'), | |||||
// floatingActionButton: _buildFloatWidget(), | // floatingActionButton: _buildFloatWidget(), | ||||
floatingActionButtonLocation: _CustomFloatingActionButtonLocation(FloatingActionButtonLocation.endFloat, 0, -100), | floatingActionButtonLocation: _CustomFloatingActionButtonLocation(FloatingActionButtonLocation.endFloat, 0, -100), | ||||
body: Column(children: _buildFirstWidget(model)), | body: Column(children: _buildFirstWidget(model)), | ||||
@@ -241,9 +221,9 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single | |||||
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)); | |||||
// 没有appbar并且没有tabbar,则给第一个元素加边距 | |||||
if (!_isHasAppbar && !_isHasTabBar) { | |||||
result.insert(0, SizedBox(height: MediaQueryData.fromWindow(window).padding.top, child: Container(color: HexColor.fromHex('#FF4242'),),)); | |||||
} | } | ||||
return result; | return result; | ||||
@@ -260,7 +240,7 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single | |||||
} catch (e, s) { | } catch (e, s) { | ||||
Logger.warn(e, s); | Logger.warn(e, s); | ||||
} | } | ||||
String parentTitle = !EmptyUtil.isEmpty(widget?.data) ? widget?.data['title_1'] ?? '' : ''; | |||||
String parentTitle = !EmptyUtil.isEmpty(widget?.data) ? widget?.data['title'] ?? '' : ''; | |||||
_isHasAppbar = true; | _isHasAppbar = true; | ||||
return AppBar( | return AppBar( | ||||
backgroundColor: HexColor.fromHex(null != data ? data['app_bar_bg_color'] ?? '#FFFFFF' : '#FFFFFF'), | backgroundColor: HexColor.fromHex(null != data ? data['app_bar_bg_color'] ?? '#FFFFFF' : '#FFFFFF'), | ||||
@@ -316,17 +296,17 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single | |||||
result.add(Container( | result.add(Container( | ||||
height: 40, | height: 40, | ||||
width: double.infinity, | width: double.infinity, | ||||
// color: HexColor.fromHex('#FFFFFF'), | |||||
color: HexColor.fromHex(data['bg_color']), | |||||
child: TabBar( | child: TabBar( | ||||
controller: _tabController, | controller: _tabController, | ||||
isScrollable: /*listStyle.length <= 5 ? false : */ true, | isScrollable: /*listStyle.length <= 5 ? false : */ true, | ||||
labelColor: HexColor.fromHex('#FF4242'), | |||||
labelColor: HexColor.fromHex(data['choose_text_color'] ?? '#FF4242'), | |||||
labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), | labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), | ||||
unselectedLabelColor: HexColor.fromHex('#999999'), | |||||
unselectedLabelColor: HexColor.fromHex(data['text_color'] ?? '#999999'), | |||||
unselectedLabelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), | unselectedLabelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), | ||||
indicatorSize: TabBarIndicatorSize.label, | indicatorSize: TabBarIndicatorSize.label, | ||||
indicator: MaterialIndicator( | indicator: MaterialIndicator( | ||||
color: HexColor.fromHex('#FF4242'), | |||||
color: HexColor.fromHex(data['choose_color'] ?? '#FF4242'), | |||||
bottomLeftRadius: 1.25, | bottomLeftRadius: 1.25, | ||||
topLeftRadius: 1.25, | topLeftRadius: 1.25, | ||||
topRightRadius: 1.25, | topRightRadius: 1.25, | ||||
@@ -35,8 +35,9 @@ 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/wechat_teacher_page/wechat_teacher_page.dart'; | ||||
import 'package:zhiying_base_widget/pages/withdraw_page/withdraw_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/banner/custom_banner_widget.dart'; | ||||
import 'package:zhiying_base_widget/widgets/custom/goods/custom_goods_widget.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/goods/custom_goods_creater.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/multi_nav/custom_quick_entry.dart'; | import 'package:zhiying_base_widget/widgets/custom/multi_nav/custom_quick_entry.dart'; | ||||
import 'package:zhiying_base_widget/widgets/custom/notice/custom_notice_widget.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/search/custom_search_widget.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'; | import 'package:zhiying_base_widget/widgets/custom/slide_banner/custom_slide_banner_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/goods_details/footer/goods_details_footer_widget.dart'; | import 'package:zhiying_base_widget/widgets/goods_details/footer/goods_details_footer_widget.dart'; | ||||
@@ -46,7 +47,6 @@ import 'package:zhiying_base_widget/widgets/goods_details/store/store_widget.dar | |||||
import 'package:zhiying_base_widget/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart'; | import 'package:zhiying_base_widget/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_notice/home_notice_widget.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_slide_banner/home_slide_banner_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_slide_banner/home_slide_banner_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_sreach/home_sreach_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_sreach/home_sreach_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_appbar/hot_ranking_appbar.dart'; | import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_appbar/hot_ranking_appbar.dart'; | ||||
@@ -80,7 +80,7 @@ import 'widgets/goods_details/detail_img/goods_details_img.dart'; | |||||
import 'widgets/goods_details/evaluate/goods_details_evaluate_widget.dart'; | import 'widgets/goods_details/evaluate/goods_details_evaluate_widget.dart'; | ||||
import 'widgets/goods_details/recommend/goods_detail_commend_creater.dart'; | import 'widgets/goods_details/recommend/goods_detail_commend_creater.dart'; | ||||
import 'widgets/goods_details/title/goods_details_title_widget.dart'; | import 'widgets/goods_details/title/goods_details_title_widget.dart'; | ||||
import 'widgets/home/home_quick_entry/home_quick_entry.dart'; | |||||
import 'widgets/home/home_auth/home_auth.dart'; | |||||
import 'widgets/home/home_sreach/home_sreach_creater.dart'; | import 'widgets/home/home_sreach/home_sreach_creater.dart'; | ||||
import 'widgets/search/history_tag/search_history_tag.dart'; | import 'widgets/search/history_tag/search_history_tag.dart'; | ||||
import 'widgets/search/hot_tag/search_hot_tag_widget.dart'; | import 'widgets/search/hot_tag/search_hot_tag_widget.dart'; | ||||
@@ -136,19 +136,19 @@ class BaseWidgetRegister { | |||||
// 缓存可能用到的数据,预加载 | // 缓存可能用到的数据,预加载 | ||||
Application.addMethod(() { | Application.addMethod(() { | ||||
// 精选的数据 | // 精选的数据 | ||||
NetUtil.post('/api/v1/rec/featured?page=1', method: NetMethod.GET, cache: true); | |||||
NetUtil.post('/api/v1/rec/featured?page=1', method: NetMethod.GET, cache: true, showToast: false); | |||||
// 淘宝的数据 | // 淘宝的数据 | ||||
NetUtil.post('/api/v1/rec/taobao?page=1', method: NetMethod.GET, cache: true); | |||||
NetUtil.post('/api/v1/rec/taobao?page=1', method: NetMethod.GET, cache: true, showToast: false); | |||||
// 京东 | // 京东 | ||||
NetUtil.post('/api/v1/rec/jd?page=1', method: NetMethod.GET, cache: true); | |||||
NetUtil.post('/api/v1/rec/jd?page=1', method: NetMethod.GET, cache: true, showToast: false); | |||||
// 唯品会 | // 唯品会 | ||||
NetUtil.post('/api/v1/rec/vip?page=1', method: NetMethod.GET, cache: true); | |||||
NetUtil.post('/api/v1/rec/vip?page=1', method: NetMethod.GET, cache: true, showToast: false); | |||||
// 拼多多 | // 拼多多 | ||||
NetUtil.post('/api/v1/rec/pdd?page=1', method: NetMethod.GET, cache: true); | |||||
NetUtil.post('/api/v1/rec/pdd?page=1', method: NetMethod.GET, cache: true, showToast: false); | |||||
// 苏宁 | // 苏宁 | ||||
NetUtil.post('/api/v1/rec/suning?page=1', method: NetMethod.GET, cache: true); | |||||
NetUtil.post('/api/v1/rec/suning?page=1', method: NetMethod.GET, cache: true, showToast: false); | |||||
// 考拉 | // 考拉 | ||||
NetUtil.post('/api/v1/rec/kaola?page=1', method: NetMethod.GET, cache: true); | |||||
NetUtil.post('/api/v1/rec/kaola?page=1', method: NetMethod.GET, cache: true, showToast: false); | |||||
return null; | return null; | ||||
}); | }); | ||||
@@ -247,7 +247,7 @@ class BaseWidgetRegister { | |||||
// WidgetFactory.regist('multi_nav', DefaultWidgetCreater((model) => HomeQuickEntry(model))); | // WidgetFactory.regist('multi_nav', DefaultWidgetCreater((model) => HomeQuickEntry(model))); | ||||
/// 滚动公告 | /// 滚动公告 | ||||
WidgetFactory.regist('index_placard', DefaultWidgetCreater((model) => HomeNoticeWidget(model))); | |||||
WidgetFactory.regist('index_placard', DefaultWidgetCreater((model) => CustomNoticeWidget(model))); | |||||
/// 不可以滚动banner | /// 不可以滚动banner | ||||
WidgetFactory.regist('index_banner_one', HomeBannerCreater()); | WidgetFactory.regist('index_banner_one', HomeBannerCreater()); | ||||
@@ -374,5 +374,9 @@ class BaseWidgetRegister { | |||||
WidgetFactory.regist('banner', DefaultWidgetCreater((model) => CustomBannerWidget(model))); | WidgetFactory.regist('banner', DefaultWidgetCreater((model) => CustomBannerWidget(model))); | ||||
// 商品列表 | // 商品列表 | ||||
WidgetFactory.regist('product', CustomGoodsCreater()); | WidgetFactory.regist('product', CustomGoodsCreater()); | ||||
// 公告头条 | |||||
WidgetFactory.regist('placard', DefaultWidgetCreater((model) => CustomNoticeWidget(model))); | |||||
// 授权 | |||||
WidgetFactory.regist('audit_tip', DefaultWidgetCreater((model) => HomeAuth(model))); | |||||
} | } | ||||
} | } |
@@ -25,16 +25,6 @@ class CustomBannerWidget extends StatelessWidget { | |||||
RouterUtil.route(model, model.toJson(), context); | 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 | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
/// 空视图 | /// 空视图 | ||||
@@ -44,9 +34,17 @@ class CustomBannerWidget extends StatelessWidget { | |||||
return Container( | return Container( | ||||
width: double.infinity, | width: double.infinity, | ||||
height: 90, | |||||
// color: Colors.red, | |||||
padding: EdgeInsets.only(top: _convert(_model?.topMargin), left: 12.5, right: 12.5), | |||||
// height: 98, | |||||
margin: EdgeInsets.only(top: ParseUtil.stringParseDouble(_model?.topMargin)), | |||||
padding: EdgeInsets.symmetric(horizontal: ParseUtil.stringParseDouble(_model?.leftRightMargin, defVal: 12.5)), | |||||
decoration: BoxDecoration( | |||||
// color: Colors.red, | |||||
borderRadius: BorderRadius.only( | |||||
bottomLeft: Radius.circular(ParseUtil.stringParseDouble(_model?.bottomLeftRadius)), | |||||
bottomRight: Radius.circular(ParseUtil.stringParseDouble(_model?.bottomRightRadius)), | |||||
topLeft: Radius.circular(ParseUtil.stringParseDouble(_model?.topLeftRadius)), | |||||
topRight: Radius.circular(ParseUtil.stringParseDouble(_model?.topRightRadius)), | |||||
)), | |||||
child: _buildMainWidget(context, _model?.moduleType, _model?.listStyle), | child: _buildMainWidget(context, _model?.moduleType, _model?.listStyle), | ||||
); | ); | ||||
} | } | ||||
@@ -196,11 +194,9 @@ class CustomBannerWidget extends StatelessWidget { | |||||
behavior: HitTestBehavior.opaque, | behavior: HitTestBehavior.opaque, | ||||
onTap: () => _itemOnClick(context, e), | onTap: () => _itemOnClick(context, e), | ||||
child: Container( | child: Container( | ||||
height: double.infinity, | |||||
width: double.infinity, | width: double.infinity, | ||||
child: CachedNetworkImage( | child: CachedNetworkImage( | ||||
imageUrl: e?.img ?? '', | imageUrl: e?.img ?? '', | ||||
fit: BoxFit.fitWidth, | |||||
)), | )), | ||||
), | ), | ||||
)) | )) | ||||
@@ -11,11 +11,30 @@ class CustomBannerModel { | |||||
String isShow; | String isShow; | ||||
String topMargin; | String topMargin; | ||||
String leftRightMargin; | String leftRightMargin; | ||||
String topLeftRadius; | |||||
String topRightRadius; | |||||
String bottomLeftRadius; | |||||
String bottomRightRadius; | |||||
List<CustomBannerListStyle> listStyle; | List<CustomBannerListStyle> listStyle; | ||||
int moduleKeyId; | 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({ | |||||
this.name, | |||||
this.desc, | |||||
this.moduleType, | |||||
this.moduleKey, | |||||
this.isTopMargin, | |||||
this.isLeftRightMargin, | |||||
this.isShow, | |||||
this.topMargin, | |||||
this.leftRightMargin, | |||||
this.listStyle, | |||||
this.moduleKeyId, | |||||
this.topLeftRadius, | |||||
this.topRightRadius, | |||||
this.bottomLeftRadius, | |||||
this.bottomRightRadius, | |||||
}); | |||||
CustomBannerModel.fromJson(Map<String, dynamic> json) { | CustomBannerModel.fromJson(Map<String, dynamic> json) { | ||||
name = json['name']; | name = json['name']; | ||||
@@ -27,6 +46,10 @@ class CustomBannerModel { | |||||
isShow = json['is_show']; | isShow = json['is_show']; | ||||
topMargin = json['top_margin']; | topMargin = json['top_margin']; | ||||
leftRightMargin = json['left_right_margin']; | leftRightMargin = json['left_right_margin']; | ||||
topLeftRadius = json['top_left_radius']; | |||||
topRightRadius = json['top_right_radius']; | |||||
bottomLeftRadius = json['bottom_left_radius']; | |||||
bottomRightRadius = json['bottom_right_radius']; | |||||
if (json['list_style'] != null) { | if (json['list_style'] != null) { | ||||
listStyle = new List<CustomBannerListStyle>(); | listStyle = new List<CustomBannerListStyle>(); | ||||
json['list_style'].forEach((v) { | json['list_style'].forEach((v) { | ||||
@@ -47,6 +70,10 @@ class CustomBannerModel { | |||||
data['is_show'] = this.isShow; | data['is_show'] = this.isShow; | ||||
data['top_margin'] = this.topMargin; | data['top_margin'] = this.topMargin; | ||||
data['left_right_margin'] = this.leftRightMargin; | data['left_right_margin'] = this.leftRightMargin; | ||||
data['top_left_radius'] = this.topLeftRadius; | |||||
data['top_right_radius'] = this.topRightRadius; | |||||
data['bottom_left_radius'] = this.bottomLeftRadius; | |||||
data['bottom_right_radius'] = this.bottomRightRadius; | |||||
if (this.listStyle != null) { | if (this.listStyle != null) { | ||||
data['list_style'] = this.listStyle.map((v) => v.toJson()).toList(); | data['list_style'] = this.listStyle.map((v) => v.toJson()).toList(); | ||||
} | } | ||||
@@ -55,7 +82,7 @@ class CustomBannerModel { | |||||
} | } | ||||
} | } | ||||
class CustomBannerListStyle extends SkipModel{ | |||||
class CustomBannerListStyle extends SkipModel { | |||||
String name; | String name; | ||||
String img; | String img; | ||||
String locationType; | String locationType; | ||||
@@ -79,7 +106,7 @@ class CustomBannerListStyle extends SkipModel{ | |||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
final Map<String, dynamic> data = super.toJson(); | final Map<String, dynamic> data = super.toJson(); | ||||
data['name'] = this.name; | data['name'] = this.name; | ||||
data['img'] = this.img; | data['img'] = this.img; | ||||
data['location_type'] = this.locationType; | data['location_type'] = this.locationType; | ||||
@@ -0,0 +1,6 @@ | |||||
/// | |||||
/// 商品分类点击的回调 | |||||
/// | |||||
abstract class CategoryGoodsOnClickCallBack{ | |||||
void onTap(int index, String providerType); | |||||
} |
@@ -0,0 +1,54 @@ | |||||
import 'dart:convert'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/goods/category_goods/category_goods_callback.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/bloc/home_goods_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/bloc/home_goods_header_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'custom_goods.dart'; | |||||
import 'custom_goods_header.dart'; | |||||
class CategoryGoodsListCreater extends WidgetCreater { | |||||
@override | |||||
List<Widget> createWidgets(Map<String, dynamic> model) { | |||||
print('创建商品列表'); | |||||
Map<String, dynamic> json = {}; | |||||
try { | |||||
json = jsonDecode(model['data']); | |||||
} catch (e) {} | |||||
// 上边距 | |||||
Widget padding = SliverToBoxAdapter(child: Container(margin: EdgeInsets.only(top: ParseUtil.stringParseDouble(null != json ? json['top_margin'] : '0')))); | |||||
// 商品列表 | |||||
HomeGoodsBloc goodsBloc = HomeGoodsBloc(); | |||||
Widget goodsList = CustomGoods(model, bloc: goodsBloc); | |||||
// Widget goodsList = BlocProvider<HomeGoodsBloc>( | |||||
// bloc: goodsBloc, | |||||
// child: CustomGoodsContainer(model), | |||||
// ); | |||||
// 商品头部 | |||||
// Widget _widget = CustomGoodsHeader(model, goodsBloc); | |||||
Widget _widget = BlocProvider<HomeGoodsHeaderBloc>( | |||||
bloc: HomeGoodsHeaderBloc(), | |||||
child: CustomGoodsHeaderContainer(model, goodsBloc), | |||||
); | |||||
Widget header = SliverPersistentHeader(pinned: true, floating: false, delegate: CustomGoodsHeaderDelegate(_widget)); | |||||
return [ | |||||
// 边距 | |||||
padding, | |||||
// 头部 | |||||
header, | |||||
// 列表 | |||||
goodsList | |||||
]; | |||||
} | |||||
@override | |||||
bool isSliverChild() { | |||||
return true; | |||||
} | |||||
} |
@@ -0,0 +1,35 @@ | |||||
import 'dart:convert'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/bloc/home_goods_header_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'custom_goods2.dart'; | |||||
import 'custom_goods_header2.dart'; | |||||
class CategoryGoodsListCreater2 extends WidgetCreater { | |||||
@override | |||||
List<Widget> createWidgets(Map<String, dynamic> model) { | |||||
print('创建商品列表'); | |||||
Map<String, dynamic> json = {}; | |||||
try { | |||||
json = jsonDecode(model['data']); | |||||
} catch (e) {} | |||||
final GlobalKey<CustomGoodsContainer2State> globalKey = GlobalKey(); | |||||
Widget padding = SliverToBoxAdapter(child: Container(margin: EdgeInsets.only(top: ParseUtil.stringParseDouble(null != json ? json['top_margin'] : '0')))); | |||||
Widget goodsList = CustomGoods2(model, globalKey: globalKey,); | |||||
Widget _widget = BlocProvider<HomeGoodsHeaderBloc>(bloc: HomeGoodsHeaderBloc(), child: CustomGoodsHeader2(model, globalKey: globalKey,)); | |||||
Widget head = SliverPersistentHeader(pinned: true, floating: false, delegate: CustomGoodsHeaderDelegate2(_widget)); | |||||
return [ | |||||
padding, | |||||
head, | |||||
goodsList, | |||||
]; | |||||
} | |||||
@override | |||||
bool isSliverChild() { | |||||
return true; | |||||
} | |||||
} |
@@ -0,0 +1,155 @@ | |||||
import 'dart:convert' as convert; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:provider/provider.dart'; | |||||
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/goods/category_goods/category_goods_callback.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/bloc/home_goods_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_item.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_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_style_model.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class CustomGoods extends StatefulWidget implements CategoryGoodsOnClickCallBack { | |||||
final Map<String, dynamic> data; | |||||
HomeGoodsBloc bloc; | |||||
CustomGoods(this.data, {this.bloc, Key key,}) : super(key: key); | |||||
@override | |||||
_CustomGoodsState createState() => _CustomGoodsState(); | |||||
@override | |||||
void onTap(int index, String providerType) { | |||||
Logger.warn('onCallBack : index = $index, providerType = $providerType'); | |||||
} | |||||
} | |||||
class _CustomGoodsState extends State<CustomGoods> { | |||||
@override | |||||
void initState() { | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocProvider<HomeGoodsBloc>( | |||||
bloc: widget?.bloc ?? HomeGoodsBloc(), | |||||
child: CustomGoodsContainer(widget.data), | |||||
); | |||||
} | |||||
@override | |||||
void dispose() { | |||||
widget?.bloc?.dispose(); | |||||
super.dispose(); | |||||
} | |||||
} | |||||
class CustomGoodsContainer extends StatefulWidget { | |||||
final Map<String, dynamic> data; | |||||
CustomGoodsContainer(this.data, {Key key}) : super(key: key); | |||||
@override | |||||
_CustomGoodsContainerState createState() => _CustomGoodsContainerState(); | |||||
} | |||||
class _CustomGoodsContainerState extends State<CustomGoodsContainer> { | |||||
HomeGoodsBloc _bloc; | |||||
String _provider = ''; | |||||
HomeGoodsStyleModel _style; | |||||
bool _isFirstLoading = true; | |||||
@override | |||||
void initState() { | |||||
_bloc = BlocProvider.of<HomeGoodsBloc>(context); | |||||
String d = widget.data['data']; | |||||
dynamic json = convert.jsonDecode(d); | |||||
_style = HomeGoodsStyleModel.fromJson(Map<String, dynamic>.from(json)); | |||||
// widget.eventBus.on<HomeGoodsHeaderEvent>().listen((data) { | |||||
// // if (!_isFirstLoading) { | |||||
// // // 老板说打开app的时候,第一次加载不要显示loading | |||||
// // Loading.show(context); | |||||
// // } | |||||
// _isFirstLoading = false; | |||||
// _provider = data.provider; | |||||
// _bloc.loadMore(_provider); | |||||
// }); | |||||
// TODO | |||||
super.initState(); | |||||
} | |||||
@override | |||||
void didChangeDependencies() { | |||||
super.didChangeDependencies(); | |||||
print('didChangeDependencies'); | |||||
bool isNeedLoadMore = Provider.of<MainPageNotifier>(context).scrollEnd; | |||||
if (isNeedLoadMore && _provider != '') { | |||||
changeProviderOrLoadMore(_provider); | |||||
} | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return StreamBuilder<List<HomeGoodsModel>>( | |||||
stream: _bloc.outData, | |||||
builder: (BuildContext context, AsyncSnapshot snapshot) { | |||||
// if (snapshot.data == null) { | |||||
// return SliverToBoxAdapter( | |||||
// child: HomeGoodsSkeleton(), | |||||
// ); | |||||
// } | |||||
// Loading.dismiss(); | |||||
List<HomeGoodsModel> goods = snapshot.data; | |||||
int column = int.tryParse(_style.listColumn ?? '1'); | |||||
column = column <= 0 ? 1 : column; | |||||
int count = ((goods?.length ?? 0) / column).ceil(); | |||||
return SliverList( | |||||
delegate: SliverChildBuilderDelegate((context, index) { | |||||
if (column == 1) { | |||||
return HomeGoodsItemSingle( | |||||
goods[index], | |||||
_style, | |||||
data: widget.data, | |||||
); | |||||
} else { | |||||
// return Container(color: Colors.red, height: 126,margin: EdgeInsets.all(10),); | |||||
return Padding( | |||||
padding: const EdgeInsets.only(left: 5, right: 5), | |||||
child: Row( | |||||
children: List.generate(column, (c) { | |||||
int i = index * column + c; | |||||
return Expanded( | |||||
child: i < goods.length | |||||
? HomeGoodsItem( | |||||
goods[i], | |||||
_style, | |||||
data: widget.data, | |||||
) | |||||
: Container(), | |||||
); | |||||
}).toList(), | |||||
), | |||||
); | |||||
} | |||||
}, childCount: count), | |||||
); | |||||
}, | |||||
); | |||||
} | |||||
// Global Key | |||||
void changeProviderOrLoadMore(String provider){ | |||||
_bloc.loadMore(_bloc.providerss); | |||||
} | |||||
} |
@@ -0,0 +1,136 @@ | |||||
import 'dart:convert' as convert; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:provider/provider.dart'; | |||||
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/goods/category_goods/category_goods_callback.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/bloc/home_goods_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_item.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_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_style_model.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class CustomGoods2 extends StatefulWidget { | |||||
final Map<String, dynamic> data; | |||||
final GlobalKey<CustomGoodsContainer2State> globalKey; | |||||
CustomGoods2( | |||||
this.data, { | |||||
this.globalKey, | |||||
Key key, | |||||
}) : super(key: key); | |||||
@override | |||||
_CustomGoods2State createState() => _CustomGoods2State(); | |||||
} | |||||
class _CustomGoods2State extends State<CustomGoods2> { | |||||
@override | |||||
void initState() { | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocProvider<HomeGoodsBloc>( | |||||
bloc: HomeGoodsBloc(), | |||||
child: CustomGoodsContainer2(widget.data, key: widget.globalKey,), | |||||
); | |||||
} | |||||
@override | |||||
void dispose() { | |||||
super.dispose(); | |||||
} | |||||
} | |||||
class CustomGoodsContainer2 extends StatefulWidget { | |||||
final Map<String, dynamic> data; | |||||
CustomGoodsContainer2(this.data, {Key key}) : super(key: key); | |||||
@override | |||||
CustomGoodsContainer2State createState() => CustomGoodsContainer2State(); | |||||
} | |||||
class CustomGoodsContainer2State extends State<CustomGoodsContainer2> { | |||||
HomeGoodsBloc _bloc; | |||||
String _provider = ''; | |||||
HomeGoodsStyleModel _style; | |||||
@override | |||||
void initState() { | |||||
_bloc = BlocProvider.of<HomeGoodsBloc>(context); | |||||
String d = widget.data['data']; | |||||
dynamic json = convert.jsonDecode(d); | |||||
_style = HomeGoodsStyleModel.fromJson(Map<String, dynamic>.from(json)); | |||||
super.initState(); | |||||
} | |||||
@override | |||||
void didChangeDependencies() { | |||||
super.didChangeDependencies(); | |||||
print('didChangeDependencies'); | |||||
bool isNeedLoadMore = Provider.of<MainPageNotifier>(context).scrollEnd; | |||||
if (isNeedLoadMore && _provider != '') { | |||||
changeProviderOrLoadMore(_provider); | |||||
} | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return StreamBuilder<List<HomeGoodsModel>>( | |||||
stream: _bloc.outData, | |||||
builder: (BuildContext context, AsyncSnapshot snapshot) { | |||||
// if (snapshot.data == null) { | |||||
// return SliverToBoxAdapter( | |||||
// child: HomeGoodsSkeleton(), | |||||
// ); | |||||
// } | |||||
// Loading.dismiss(); | |||||
List<HomeGoodsModel> goods = snapshot.data; | |||||
int column = int.tryParse(_style.listColumn ?? '1'); | |||||
column = column <= 0 ? 1 : column; | |||||
int count = ((goods?.length ?? 0) / column).ceil(); | |||||
return SliverList( | |||||
delegate: SliverChildBuilderDelegate((context, index) { | |||||
if (column == 1) { | |||||
return HomeGoodsItemSingle( | |||||
goods[index], | |||||
_style, | |||||
data: widget.data, | |||||
); | |||||
} else { | |||||
// return Container(color: Colors.red, height: 126,margin: EdgeInsets.all(10),); | |||||
return Padding( | |||||
padding: const EdgeInsets.only(left: 5, right: 5), | |||||
child: Row( | |||||
children: List.generate(column, (c) { | |||||
int i = index * column + c; | |||||
return Expanded( | |||||
child: i < goods.length | |||||
? HomeGoodsItem( | |||||
goods[i], | |||||
_style, | |||||
data: widget.data, | |||||
) | |||||
: Container(), | |||||
); | |||||
}).toList(), | |||||
), | |||||
); | |||||
} | |||||
}, childCount: count), | |||||
); | |||||
}, | |||||
); | |||||
} | |||||
// Global Key | |||||
void changeProviderOrLoadMore(String provider) { | |||||
Logger.warn('_CustomGoodsContainer2State ======================= provider = $provider'); | |||||
_provider = provider; | |||||
_bloc?.loadMore(_bloc.providerss); | |||||
} | |||||
} |
@@ -0,0 +1,166 @@ | |||||
import 'dart:convert' as convert; | |||||
import 'dart:ui' as ui; | |||||
import 'package:event_bus/event_bus.dart'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/goods/category_goods/category_goods_callback.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/bloc/home_goods_header_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_header_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_style_model.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'custom_goods.dart'; | |||||
class CustomGoodsHeaderDelegate extends SliverPersistentHeaderDelegate { | |||||
final Widget child; | |||||
CustomGoodsHeaderDelegate(this.child) : super(); | |||||
@override | |||||
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { | |||||
print('${shrinkOffset.toString()} ${overlapsContent.toString()}'); | |||||
return child; | |||||
} | |||||
@override | |||||
double get maxExtent => 64.0; | |||||
@override | |||||
double get minExtent => 64.0; | |||||
@override | |||||
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => false; // 如果内容需要更新,设置为true | |||||
} | |||||
class CustomGoodsHeader extends StatelessWidget { | |||||
final Map<String, dynamic> model; | |||||
final CategoryGoodsOnClickCallBack callBack; | |||||
const CustomGoodsHeader( | |||||
this.model, | |||||
this.callBack, { | |||||
Key key, | |||||
}) : super(key: key); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocProvider<HomeGoodsHeaderBloc>( | |||||
bloc: HomeGoodsHeaderBloc(), | |||||
child: CustomGoodsHeaderContainer(model, callBack), | |||||
); | |||||
} | |||||
} | |||||
class CustomGoodsHeaderContainer extends StatefulWidget { | |||||
final Map<String, dynamic> model; | |||||
final CategoryGoodsOnClickCallBack callBack; | |||||
CustomGoodsHeaderContainer(this.model, this.callBack, {Key key}) : super(key: key); | |||||
@override | |||||
_CustomGoodsHeaderContainerState createState() => _CustomGoodsHeaderContainerState(); | |||||
} | |||||
class _CustomGoodsHeaderContainerState extends State<CustomGoodsHeaderContainer> with TickerProviderStateMixin { | |||||
HomeGoodsStyleModel _style; | |||||
List<Widget> _widgets = List(); | |||||
TabController _tabController; | |||||
int _currentIndex = 0; | |||||
@override | |||||
void initState() { | |||||
String d = widget.model['data']; | |||||
dynamic json = convert.jsonDecode(d); | |||||
_style = HomeGoodsStyleModel.fromJson(Map<String, dynamic>.from(json)); | |||||
_tabController = TabController(length: _style?.recommendList?.length ?? 0, vsync: this); | |||||
if (_style.recommendList.first != null) { | |||||
// TODO | |||||
widget.callBack.onTap(0, _style.recommendList.first.type); | |||||
} | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
_widgets.clear(); | |||||
for (int index = 0; index < _style.recommendList.length; index++) { | |||||
_widgets.add(_HomeGoodsHeaderItem( | |||||
_style.recommendList[index], | |||||
titleTextColor: index == _currentIndex ? (HexColor.fromHex(_style.tilteTextSelectedColor ?? '#FF4242')) : (HexColor.fromHex(_style.tilteTextColor ?? '#333333')), | |||||
subtitleTextColor: index == _currentIndex ? (HexColor.fromHex(_style.subtitleTextSelectedColor ?? '#ffffff')) : (HexColor.fromHex(_style.subtitleTextColor ?? '#999999')), | |||||
subtitleBgColor: index == _currentIndex ? HexColor.fromHex(_style.subtitleBgColor ?? '#FF4242') : Colors.transparent, | |||||
)); | |||||
} | |||||
return Container( | |||||
width: double.infinity, | |||||
height: double.infinity, | |||||
color: Color(0xfff9f9f9), | |||||
// color: Colors.yellow, | |||||
child: TabBar( | |||||
indicatorColor: Colors.transparent, | |||||
controller: _tabController, | |||||
isScrollable: true, | |||||
tabs: _widgets, | |||||
onTap: (index) { | |||||
//TODO | |||||
widget.callBack.onTap(index, _style.recommendList[index].type); | |||||
setState(() { | |||||
_currentIndex = index; | |||||
}); | |||||
}, | |||||
), | |||||
); | |||||
} | |||||
} | |||||
class _HomeGoodsHeaderItem extends StatelessWidget { | |||||
final HomeGoodsHeaderModel model; | |||||
final ui.Color titleTextColor; | |||||
final ui.Color subtitleTextColor; | |||||
final ui.Color subtitleBgColor; | |||||
const _HomeGoodsHeaderItem( | |||||
this.model, { | |||||
Key key, | |||||
this.titleTextColor, | |||||
this.subtitleBgColor, | |||||
this.subtitleTextColor, | |||||
}) : super(key: key); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return Container( | |||||
// width: 60, | |||||
// height: 54, | |||||
child: Center( | |||||
child: Column( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
children: <Widget>[ | |||||
Text( | |||||
model.title, | |||||
style: TextStyle(color: titleTextColor ?? ui.Color(0xff333333), fontSize: 17, fontWeight: FontWeight.bold), | |||||
), | |||||
model.subtitle == null || model.subtitle == '' | |||||
? Container() | |||||
: Container( | |||||
margin: EdgeInsets.only(top: 4), | |||||
padding: EdgeInsets.only(left: 6, right: 6, top: 2, bottom: 2), | |||||
decoration: BoxDecoration(color: subtitleBgColor ?? Colors.transparent, borderRadius: BorderRadius.circular(18)), | |||||
child: Text( | |||||
model.subtitle ?? '', | |||||
style: TextStyle(fontSize: 10, color: subtitleTextColor ?? Color(0xff999999)), | |||||
textAlign: TextAlign.center, | |||||
), | |||||
), | |||||
], | |||||
), | |||||
)); | |||||
} | |||||
} |
@@ -0,0 +1,170 @@ | |||||
import 'dart:convert' as convert; | |||||
import 'dart:ui' as ui; | |||||
import 'package:event_bus/event_bus.dart'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/goods/category_goods/category_goods_callback.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/goods/category_goods/custom_goods2.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/bloc/home_goods_header_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_header_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_style_model.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'custom_goods.dart'; | |||||
class CustomGoodsHeaderDelegate2 extends SliverPersistentHeaderDelegate { | |||||
final Widget child; | |||||
CustomGoodsHeaderDelegate2(this.child) : super(); | |||||
@override | |||||
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { | |||||
print('${shrinkOffset.toString()} ${overlapsContent.toString()}'); | |||||
return child; | |||||
} | |||||
@override | |||||
double get maxExtent => 64.0; | |||||
@override | |||||
double get minExtent => 64.0; | |||||
@override | |||||
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => false; // 如果内容需要更新,设置为true | |||||
} | |||||
class CustomGoodsHeader2 extends StatelessWidget { | |||||
final Map<String, dynamic> model; | |||||
final GlobalKey<CustomGoodsContainer2State> globalKey; | |||||
const CustomGoodsHeader2( | |||||
this.model, { | |||||
this.globalKey, | |||||
Key key, | |||||
}) : super(key: key); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocProvider<HomeGoodsHeaderBloc>( | |||||
bloc: HomeGoodsHeaderBloc(), | |||||
child: CustomGoodsHeaderContainer2( | |||||
model, | |||||
globalKey: globalKey, | |||||
), | |||||
); | |||||
} | |||||
} | |||||
class CustomGoodsHeaderContainer2 extends StatefulWidget { | |||||
final Map<String, dynamic> model; | |||||
final GlobalKey<CustomGoodsContainer2State> globalKey; | |||||
CustomGoodsHeaderContainer2(this.model, {this.globalKey, Key key}) : super(key: key); | |||||
@override | |||||
_CustomGoodsHeaderContainer2State createState() => _CustomGoodsHeaderContainer2State(); | |||||
} | |||||
class _CustomGoodsHeaderContainer2State extends State<CustomGoodsHeaderContainer2> with TickerProviderStateMixin { | |||||
HomeGoodsStyleModel _style; | |||||
List<Widget> _widgets = List(); | |||||
TabController _tabController; | |||||
int _currentIndex = 0; | |||||
@override | |||||
void initState() { | |||||
String d = widget.model['data']; | |||||
dynamic json = convert.jsonDecode(d); | |||||
_style = HomeGoodsStyleModel.fromJson(Map<String, dynamic>.from(json)); | |||||
_tabController = TabController(length: _style?.recommendList?.length ?? 0, vsync: this); | |||||
if (_style.recommendList.first != null) { | |||||
// TODO | |||||
widget?.globalKey?.currentState?.changeProviderOrLoadMore(_style.recommendList.first.type); | |||||
} | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
_widgets.clear(); | |||||
for (int index = 0; index < _style.recommendList.length; index++) { | |||||
_widgets.add(_HomeGoodsHeaderItem( | |||||
_style.recommendList[index], | |||||
titleTextColor: index == _currentIndex ? (HexColor.fromHex(_style.tilteTextSelectedColor ?? '#FF4242')) : (HexColor.fromHex(_style.tilteTextColor ?? '#333333')), | |||||
subtitleTextColor: index == _currentIndex ? (HexColor.fromHex(_style.subtitleTextSelectedColor ?? '#ffffff')) : (HexColor.fromHex(_style.subtitleTextColor ?? '#999999')), | |||||
subtitleBgColor: index == _currentIndex ? HexColor.fromHex(_style.subtitleBgColor ?? '#FF4242') : Colors.transparent, | |||||
)); | |||||
} | |||||
return Container( | |||||
width: double.infinity, | |||||
height: double.infinity, | |||||
color: Color(0xfff9f9f9), | |||||
// color: Colors.yellow, | |||||
child: TabBar( | |||||
indicatorColor: Colors.transparent, | |||||
controller: _tabController, | |||||
isScrollable: true, | |||||
tabs: _widgets, | |||||
onTap: (index) { | |||||
//TODO | |||||
setState(() { | |||||
_currentIndex = index; | |||||
}); | |||||
widget?.globalKey?.currentState?.changeProviderOrLoadMore(_style.recommendList[index].type); | |||||
}, | |||||
), | |||||
); | |||||
} | |||||
} | |||||
class _HomeGoodsHeaderItem extends StatelessWidget { | |||||
final HomeGoodsHeaderModel model; | |||||
final ui.Color titleTextColor; | |||||
final ui.Color subtitleTextColor; | |||||
final ui.Color subtitleBgColor; | |||||
const _HomeGoodsHeaderItem( | |||||
this.model, { | |||||
Key key, | |||||
this.titleTextColor, | |||||
this.subtitleBgColor, | |||||
this.subtitleTextColor, | |||||
}) : super(key: key); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return Container( | |||||
// width: 60, | |||||
// height: 54, | |||||
child: Center( | |||||
child: Column( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
children: <Widget>[ | |||||
Text( | |||||
model.title, | |||||
style: TextStyle(color: titleTextColor ?? ui.Color(0xff333333), fontSize: 17, fontWeight: FontWeight.bold), | |||||
), | |||||
model.subtitle == null || model.subtitle == '' | |||||
? Container() | |||||
: Container( | |||||
margin: EdgeInsets.only(top: 4), | |||||
padding: EdgeInsets.only(left: 6, right: 6, top: 2, bottom: 2), | |||||
decoration: BoxDecoration(color: subtitleBgColor ?? Colors.transparent, borderRadius: BorderRadius.circular(18)), | |||||
child: Text( | |||||
model.subtitle ?? '', | |||||
style: TextStyle(fontSize: 10, color: subtitleTextColor ?? Color(0xff999999)), | |||||
textAlign: TextAlign.center, | |||||
), | |||||
), | |||||
], | |||||
), | |||||
)); | |||||
} | |||||
} |
@@ -4,6 +4,9 @@ import 'package:zhiying_base_widget/widgets/goods_details/recommend/goods_detail | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'category_goods/category_goods_creater.dart'; | |||||
import 'category_goods/category_goods_creater2.dart'; | |||||
/// | /// | ||||
/// 通用模块的商品列表 | /// 通用模块的商品列表 | ||||
/// | /// | ||||
@@ -13,9 +16,13 @@ class CustomGoodsCreater extends WidgetCreater { | |||||
@override | @override | ||||
List<Widget> createWidgets(Map<String, dynamic> model) { | List<Widget> createWidgets(Map<String, dynamic> model) { | ||||
Map<String, dynamic> json = jsonDecode(model['data']); | Map<String, dynamic> json = jsonDecode(model['data']); | ||||
// 有Tab头部的商品列表 | |||||
if (!EmptyUtil.isEmpty(json['recommend_list'])) { | if (!EmptyUtil.isEmpty(json['recommend_list'])) { | ||||
// creater = CategoryGoodsListCreater2(); | |||||
// creater = CategoryGoodsListCreater(); | |||||
creater = GoodsListCreater(); | creater = GoodsListCreater(); | ||||
} else { | } else { | ||||
// 没有Tab头部的商品列表 | |||||
creater = GoodsDetailCommendCreater(); | creater = GoodsDetailCommendCreater(); | ||||
} | } | ||||
return creater?.createWidgets(model) ?? SliverToBoxAdapter(child: Container()); | return creater?.createWidgets(model) ?? SliverToBoxAdapter(child: Container()); |
@@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
import 'package:flutter_swiper/flutter_swiper.dart'; | import 'package:flutter_swiper/flutter_swiper.dart'; | ||||
import 'package:tab_indicator_styler/tab_indicator_styler.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||
import 'custom_quick_entry_sk.dart'; | import 'custom_quick_entry_sk.dart'; | ||||
@@ -73,7 +74,7 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
}, | }, | ||||
); | ); | ||||
} | } | ||||
Widget _getMainWidget(CustomQuickEntryModel model) { | Widget _getMainWidget(CustomQuickEntryModel model) { | ||||
// 数据总数 | // 数据总数 | ||||
int totalDataSize = model?.listStyle?.length ?? 0; | int totalDataSize = model?.listStyle?.length ?? 0; | ||||
@@ -82,7 +83,7 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
int totalRowSize = int.parse(model?.rowSize ?? '1'); | int totalRowSize = int.parse(model?.rowSize ?? '1'); | ||||
// 展示的列数 | // 展示的列数 | ||||
int columSize = int.parse(model?.columnSize ?? '5'); | |||||
int columSize = int.parse(model?.columSize ?? '5'); | |||||
// 图标的高度 | // 图标的高度 | ||||
double iconHeight = 40.0; | double iconHeight = 40.0; | ||||
@@ -113,38 +114,126 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
totalHeight = totalRowSize * (itemHeight + barMargin); | totalHeight = totalRowSize * (itemHeight + barMargin); | ||||
} | } | ||||
// 分类导航高度 | |||||
double categoryHeight = 24; | |||||
// 分类导航到多眼导航的边距 | |||||
double categoryBottomMargin = 15.0; | |||||
bool hasCategory = false; | |||||
// if(!EmptyUtil.isEmpty(model?.typeList) && model.typeList.length >= 2){ | |||||
// totalHeight = totalHeight + categoryHeight + categoryBottomMargin; | |||||
// hasCategory = true; | |||||
// } | |||||
return Container( | return Container( | ||||
color: HexColor.fromHex(widget?.model['bg_color']), | |||||
// color: Colors.yellow, | |||||
margin: EdgeInsets.only(top: ParseUtil.stringParseDouble(model?.topMargin)), | |||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex(model?.bgColor ?? ''), | |||||
// color: Colors.green, | |||||
borderRadius: BorderRadius.only( | |||||
topRight: Radius.circular(ParseUtil.stringParseDouble(model?.topRightRadius)), | |||||
topLeft: Radius.circular(ParseUtil.stringParseDouble(model?.topLeftRadius)), | |||||
bottomLeft: Radius.circular(ParseUtil.stringParseDouble(model?.bottomLeftRadius)), | |||||
bottomRight: Radius.circular(ParseUtil.stringParseDouble(model?.bottomRightRadius)), | |||||
) | |||||
), | |||||
child: Container( | child: Container( | ||||
margin: EdgeInsets.only(top: 15, bottom: totalPage > 1 ? 15 : 0), | |||||
margin: EdgeInsets.only(top: !hasCategory ? 15 : 0, bottom: totalPage > 1 ? 15 : 0), | |||||
height: totalHeight, | height: totalHeight, | ||||
// 总体高度 | // 总体高度 | ||||
width: double.infinity, | width: double.infinity, | ||||
color: HexColor.fromHex(widget?.model['bg_color']), | |||||
child: Swiper( | |||||
controller: _controller, | |||||
itemCount: totalPage, | |||||
loop: false, | |||||
itemBuilder: (context, index) { | |||||
return Container( | |||||
height: double.infinity, | |||||
// color: HexColor.fromHex(widget?.model['bg_color']), | |||||
child: Column( | |||||
children: <Widget>[ | |||||
Container( | |||||
width: double.infinity, | width: double.infinity, | ||||
padding: const EdgeInsets.symmetric(horizontal: 12.5), | |||||
child: _getPageWidget( | |||||
iconHeight: iconHeight, | |||||
titleHeight: titleHeight, | |||||
totalDataSize: totalDataSize, | |||||
totalPage: totalPage, | |||||
currentPage: index, | |||||
totalRowSize: totalRowSize, | |||||
columSize: columSize, | |||||
model: model, | |||||
itemHeight: itemHeight, | |||||
height: hasCategory ? totalHeight - categoryHeight - categoryBottomMargin : totalHeight , | |||||
child: Swiper( | |||||
controller: _controller, | |||||
itemCount: totalPage, | |||||
loop: false, | |||||
itemBuilder: (context, index) { | |||||
return Container( | |||||
height: double.infinity, | |||||
width: double.infinity, | |||||
padding: const EdgeInsets.symmetric(horizontal: 4), | |||||
child: _getPageWidget( | |||||
iconHeight: iconHeight, | |||||
titleHeight: titleHeight, | |||||
totalDataSize: totalDataSize, | |||||
totalPage: totalPage, | |||||
currentPage: index, | |||||
totalRowSize: totalRowSize, | |||||
columSize: columSize, | |||||
model: model, | |||||
itemHeight: itemHeight, | |||||
), | |||||
); | |||||
}, | |||||
pagination: totalPage <= 1 ? null : _getSwiperPaginationContorl(model, totalPage), | |||||
), | ), | ||||
); | |||||
}, | |||||
pagination: totalPage <= 1 ? null : _getSwiperPaginationContorl(model, totalPage), | |||||
) | |||||
// Container( | |||||
// margin: EdgeInsets.only(bottom: categoryBottomMargin), | |||||
// padding: const EdgeInsets.only(left: 12.5, right: 12.5), | |||||
// height: categoryHeight, | |||||
// width: double.infinity, | |||||
// child: TabBar( | |||||
// controller: tabController, | |||||
// labelColor: HexColor.fromHex('#FFFF4242'), | |||||
// unselectedLabelColor: HexColor.fromHex('#FF3C3C3C'), | |||||
// // indicatorColor: HexColor.fromHex('#FFFF4242'), | |||||
// indicator: MaterialIndicator( | |||||
// color: HexColor.fromHex('#FFFF4242'), | |||||
// height: 22, | |||||
// bottomRightRadius: 10, | |||||
// bottomLeftRadius: 10, | |||||
// topRightRadius: 10, | |||||
// topLeftRadius: 10, | |||||
// tabPosition: TabPosition.top, | |||||
// horizontalPadding: 8, | |||||
// // paintingStyle: PaintingStyle.stroke | |||||
// ), | |||||
// tabs: List.generate(5, (index) => Container(width: 50, child: Center(child: Text('热门', style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold))))), | |||||
// ), | |||||
// ), | |||||
// Expanded( | |||||
// child: TabBarView( | |||||
// controller: tabController, | |||||
// children: List.generate(5, (index) => Container( | |||||
// width: double.infinity, | |||||
// height: hasCategory ? totalHeight - categoryHeight - categoryBottomMargin : totalHeight , | |||||
// child: Swiper( | |||||
// controller: _controller, | |||||
// itemCount: totalPage, | |||||
// loop: false, | |||||
// itemBuilder: (context, index) { | |||||
// return Container( | |||||
// height: double.infinity, | |||||
// width: double.infinity, | |||||
// padding: const EdgeInsets.symmetric(horizontal: 4), | |||||
// child: _getPageWidget( | |||||
// iconHeight: iconHeight, | |||||
// titleHeight: titleHeight, | |||||
// totalDataSize: totalDataSize, | |||||
// totalPage: totalPage, | |||||
// currentPage: index, | |||||
// totalRowSize: totalRowSize, | |||||
// columSize: columSize, | |||||
// model: model, | |||||
// itemHeight: itemHeight, | |||||
// ), | |||||
// ); | |||||
// }, | |||||
// pagination: totalPage <= 1 ? null : _getSwiperPaginationContorl(model, totalPage), | |||||
// ), | |||||
// )), | |||||
// ), | |||||
// ) | |||||
], | |||||
), | ), | ||||
), | ), | ||||
); | ); | ||||
@@ -294,7 +383,7 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
} | } | ||||
/// 进度条 | /// 进度条 | ||||
SwiperPagination _getSwiperPaginationContorl(CustomQuickEntryModel model, int pageCount) { | |||||
SwiperPlugin _getSwiperPaginationContorl(CustomQuickEntryModel model, int pageCount) { | |||||
if (EmptyUtil.isEmpty(model?.pagination) || model.pagination == 'type_null' /*model.pagination_open == '0'*/) { | if (EmptyUtil.isEmpty(model?.pagination) || model.pagination == 'type_null' /*model.pagination_open == '0'*/) { | ||||
return null; | return null; | ||||
} | } | ||||
@@ -371,4 +460,83 @@ class MyNetWorkImage extends StatelessWidget { | |||||
), | ), | ||||
); | ); | ||||
} | } | ||||
// Widget _getMainWidget(CustomQuickEntryModel model) { | |||||
// // 数据总数 | |||||
// int totalDataSize = model?.listStyle?.length ?? 0; | |||||
// | |||||
// // 展示的总行数 | |||||
// int totalRowSize = 1;int.parse(model?.rowSize ?? '1'); | |||||
// | |||||
// // 展示的列数 | |||||
// int columSize = 5;int.parse(model?.columnSize ?? '5'); | |||||
// | |||||
// // 图标的高度 | |||||
// double iconHeight = 40.0; | |||||
// // 标题的高度 | |||||
// double titleHeight = 20.0; | |||||
// | |||||
// // 子元素的高度 | |||||
// double itemHeight = iconHeight; | |||||
// | |||||
// // 如果有一级标题 | |||||
// if (!EmptyUtil.isEmpty(model?.isShowTitle) && model.isShowTitle == '1') { | |||||
// itemHeight = iconHeight + titleHeight; | |||||
// } | |||||
// | |||||
// //如果有二级标题 | |||||
// if (!EmptyUtil.isEmpty(model?.isShowSubTitle) && model.isShowSubTitle == '1') { | |||||
// itemHeight = iconHeight + titleHeight * 2; | |||||
// } | |||||
// | |||||
// // 进度条的边距 | |||||
// double barMargin = 15.0; | |||||
// // 总页数 | |||||
// int totalPage = totalDataSize % (totalRowSize * columSize) == 0 ? totalDataSize ~/ (totalRowSize * columSize) : (totalDataSize ~/ (totalRowSize * columSize)) + 1; | |||||
// | |||||
// // 总体高度 = 行数 * (子元素高度 + 边距高度) + 进度条的高度 | |||||
// double totalHeight = totalRowSize * (itemHeight + barMargin) + 4; | |||||
// if (!EmptyUtil.isEmpty(model?.pagination) && model.pagination != 'type_null' /*model.pagination_open == '0'*/) { | |||||
// totalHeight = totalRowSize * (itemHeight + barMargin); | |||||
// } | |||||
// | |||||
// 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, | |||||
// // 总体高度 | |||||
// width: double.infinity, | |||||
// color: HexColor.fromHex(widget?.model['bg_color']), | |||||
// child: Swiper( | |||||
// controller: _controller, | |||||
// itemCount: totalPage, | |||||
// loop: false, | |||||
// itemBuilder: (context, index) { | |||||
// return Container( | |||||
// height: double.infinity, | |||||
// width: double.infinity, | |||||
// padding: const EdgeInsets.symmetric(horizontal: 12.5), | |||||
// child: _getPageWidget( | |||||
// iconHeight: iconHeight, | |||||
// titleHeight: titleHeight, | |||||
// totalDataSize: totalDataSize, | |||||
// totalPage: totalPage, | |||||
// currentPage: index, | |||||
// totalRowSize: totalRowSize, | |||||
// columSize: columSize, | |||||
// model: model, | |||||
// itemHeight: itemHeight, | |||||
// ), | |||||
// ); | |||||
// }, | |||||
// pagination: totalPage <= 1 ? null : _getSwiperPaginationContorl(model, totalPage), | |||||
// ), | |||||
// ), | |||||
// ); | |||||
// } | |||||
} | } |
@@ -1,3 +1,4 @@ | |||||
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'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
class CustomQuickEntryModel { | class CustomQuickEntryModel { | ||||
@@ -11,64 +12,77 @@ class CustomQuickEntryModel { | |||||
String isShow; | String isShow; | ||||
String topMargin; | String topMargin; | ||||
String leftRightMargin; | String leftRightMargin; | ||||
String topLeftRadius; | |||||
String topRightRadius; | |||||
String bottomLeftRadius; | |||||
String bottomRightRadius; | |||||
String rowSize; | String rowSize; | ||||
String columnSize; | |||||
String isShowSubTitle; | |||||
String bgColor; | |||||
String paginationSelectColor; | |||||
String paginationUnselectColor; | |||||
String isShowTitle; | String isShowTitle; | ||||
String isShowSubTitle; | |||||
String isShowCornerIcon; | String isShowCornerIcon; | ||||
String isShowCategory; | String isShowCategory; | ||||
String paginationSelectColor; | |||||
String paginationUnselectColor; | |||||
List<ListStyle> listStyle; | List<ListStyle> listStyle; | ||||
List<TypeList> typeList; | List<TypeList> typeList; | ||||
int moduleKeyId; | |||||
String titleColor; | String titleColor; | ||||
String subTitleColor; | String subTitleColor; | ||||
String columSize; | |||||
CustomQuickEntryModel({ | |||||
this.name, | |||||
this.desc, | |||||
this.pagination, | |||||
this.moduleType, | |||||
this.moduleKey, | |||||
this.isTopMargin, | |||||
this.isLeftRightMargin, | |||||
this.isShow, | |||||
this.topMargin, | |||||
this.leftRightMargin, | |||||
this.rowSize, | |||||
this.isShowSubTitle, | |||||
this.isShowCornerIcon, | |||||
this.isShowCategory, | |||||
this.paginationSelectColor, | |||||
this.paginationUnselectColor, | |||||
this.listStyle, | |||||
this.typeList, | |||||
this.moduleKeyId, | |||||
this.titleColor, | |||||
this.subTitleColor, | |||||
this.columnSize, | |||||
this.isShowTitle, | |||||
}); | |||||
CustomQuickEntryModel( | |||||
{this.name, | |||||
this.desc, | |||||
this.pagination, | |||||
this.moduleType, | |||||
this.moduleKey, | |||||
this.isTopMargin, | |||||
this.isLeftRightMargin, | |||||
this.isShow, | |||||
this.topMargin, | |||||
this.leftRightMargin, | |||||
this.topLeftRadius, | |||||
this.topRightRadius, | |||||
this.bottomLeftRadius, | |||||
this.bottomRightRadius, | |||||
this.rowSize, | |||||
this.bgColor, | |||||
this.paginationSelectColor, | |||||
this.paginationUnselectColor, | |||||
this.isShowSubTitle, | |||||
this.isShowCornerIcon, | |||||
this.isShowCategory, | |||||
this.listStyle, | |||||
this.typeList, | |||||
this.titleColor, | |||||
this.subTitleColor, | |||||
this.columSize, | |||||
this.isShowTitle, | |||||
}); | |||||
CustomQuickEntryModel.fromJson(Map<String, dynamic> json) { | CustomQuickEntryModel.fromJson(Map<String, dynamic> json) { | ||||
name = json['name']?.toString(); | |||||
desc = json['desc']?.toString(); | |||||
pagination = json['pagination']?.toString(); | |||||
moduleType = json['module_type']?.toString(); | |||||
moduleKey = json['module_key']?.toString(); | |||||
isTopMargin = json['is_top_margin']?.toString(); | |||||
isLeftRightMargin = json['is_left_right_margin']?.toString(); | |||||
isShow = json['is_show']?.toString(); | |||||
topMargin = json['top_margin']?.toString(); | |||||
leftRightMargin = json['left_right_margin']?.toString(); | |||||
name = json['name']; | |||||
desc = json['desc']; | |||||
pagination = json['pagination']; | |||||
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']; | |||||
topLeftRadius = json['top_left_radius']; | |||||
topRightRadius = json['top_right_radius']; | |||||
bottomLeftRadius = json['bottom_left_radius']; | |||||
bottomRightRadius = json['bottom_right_radius']; | |||||
rowSize = json['row_size']?.toString(); | rowSize = json['row_size']?.toString(); | ||||
columnSize = json['column_size']?.toString() ?? '5'; | |||||
isShowSubTitle = json['is_show_sub_title']?.toString(); | |||||
isShowCornerIcon = json['is_show_corner_icon']?.toString(); | |||||
isShowCategory = json['is_show_category']?.toString(); | |||||
paginationSelectColor = json['pagination_select_color']?.toString(); | |||||
paginationUnselectColor = json['pagination_unselect_color']?.toString(); | |||||
bgColor = json['bg_color']; | |||||
paginationSelectColor = json['pagination_select_color']; | |||||
paginationUnselectColor = json['pagination_unselect_color']; | |||||
isShowTitle = json['is_show_title'] ?? '1'; | |||||
isShowSubTitle = json['is_show_sub_title']; | |||||
isShowCornerIcon = json['is_show_corner_icon']; | |||||
isShowCategory = json['is_show_category']; | |||||
if (json['list_style'] != null) { | if (json['list_style'] != null) { | ||||
listStyle = new List<ListStyle>(); | listStyle = new List<ListStyle>(); | ||||
json['list_style'].forEach((v) { | json['list_style'].forEach((v) { | ||||
@@ -81,10 +95,9 @@ class CustomQuickEntryModel { | |||||
typeList.add(new TypeList.fromJson(v)); | typeList.add(new TypeList.fromJson(v)); | ||||
}); | }); | ||||
} | } | ||||
moduleKeyId = json['module_key_id']; | |||||
titleColor = json['title_color']; | titleColor = json['title_color']; | ||||
subTitleColor = json['sub_title_color']; | subTitleColor = json['sub_title_color']; | ||||
isShowTitle = '1'; | |||||
columSize = json['colum_size']?.toString(); | |||||
} | } | ||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
@@ -99,55 +112,57 @@ class CustomQuickEntryModel { | |||||
data['is_show'] = this.isShow; | data['is_show'] = this.isShow; | ||||
data['top_margin'] = this.topMargin; | data['top_margin'] = this.topMargin; | ||||
data['left_right_margin'] = this.leftRightMargin; | data['left_right_margin'] = this.leftRightMargin; | ||||
data['top_left_radius'] = this.topLeftRadius; | |||||
data['top_right_radius'] = this.topRightRadius; | |||||
data['bottom_left_radius'] = this.bottomLeftRadius; | |||||
data['bottom_right_radius'] = this.bottomRightRadius; | |||||
data['row_size'] = this.rowSize; | data['row_size'] = this.rowSize; | ||||
data['column_size'] = this.columnSize; | |||||
data['bg_color'] = this.bgColor; | |||||
data['pagination_select_color'] = this.paginationSelectColor; | |||||
data['pagination_unselect_color'] = this.paginationUnselectColor; | |||||
data['is_show_sub_title'] = this.isShowSubTitle; | data['is_show_sub_title'] = this.isShowSubTitle; | ||||
data['is_show_corner_icon'] = this.isShowCornerIcon; | data['is_show_corner_icon'] = this.isShowCornerIcon; | ||||
data['is_show_category'] = this.isShowCategory; | data['is_show_category'] = this.isShowCategory; | ||||
data['pagination_select_color'] = this.paginationSelectColor; | |||||
data['pagination_unselect_color'] = this.paginationUnselectColor; | |||||
if (this.listStyle != null) { | if (this.listStyle != null) { | ||||
data['list_style'] = this.listStyle.map((v) => v.toJson()).toList(); | data['list_style'] = this.listStyle.map((v) => v.toJson()).toList(); | ||||
} | } | ||||
if (this.typeList != null) { | if (this.typeList != null) { | ||||
data['type_list'] = this.typeList.map((v) => v.toJson()).toList(); | data['type_list'] = this.typeList.map((v) => v.toJson()).toList(); | ||||
} | } | ||||
data['module_key_id'] = this.moduleKeyId; | |||||
data['title_color'] = this.titleColor; | data['title_color'] = this.titleColor; | ||||
data['sub_title_color'] = this.subTitleColor; | data['sub_title_color'] = this.subTitleColor; | ||||
data['is_show_title'] = this.isShowTitle; | |||||
data['colum_size'] = this.columSize; | |||||
return data; | return data; | ||||
} | } | ||||
} | } | ||||
class ListStyle extends SkipModel { | |||||
String title; | |||||
class ListStyle extends SkipModel{ | |||||
String img; | String img; | ||||
String title; | |||||
String subTitle; | String subTitle; | ||||
String typeListKey; | |||||
String rightIcon; | String rightIcon; | ||||
String typeListKey; | |||||
String requiredLogin; | String requiredLogin; | ||||
String requiredTaobaoAuth; | String requiredTaobaoAuth; | ||||
String skipIdentifier; | String skipIdentifier; | ||||
ListStyle({ | |||||
this.title, | |||||
this.img, | |||||
this.subTitle, | |||||
this.typeListKey, | |||||
this.rightIcon, | |||||
this.requiredLogin, | |||||
this.requiredTaobaoAuth, | |||||
this.skipIdentifier, | |||||
}); | |||||
ListStyle( | |||||
{this.img, | |||||
this.title, | |||||
this.subTitle, | |||||
this.rightIcon, | |||||
this.typeListKey, | |||||
this.requiredLogin, | |||||
this.requiredTaobaoAuth, | |||||
this.skipIdentifier}); | |||||
ListStyle.fromJson(Map<String, dynamic> json) { | ListStyle.fromJson(Map<String, dynamic> json) { | ||||
super.fromJson(json); | super.fromJson(json); | ||||
title = json['title']; | |||||
img = json['img']; | img = json['img']; | ||||
title = json['title']; | |||||
subTitle = json['sub_title']; | subTitle = json['sub_title']; | ||||
typeListKey = json['type_list_key']; | |||||
rightIcon = json['right_icon']; | rightIcon = json['right_icon']; | ||||
typeListKey = json['type_list_key']; | |||||
requiredLogin = json['required_login']; | requiredLogin = json['required_login']; | ||||
requiredTaobaoAuth = json['required_taobao_auth']; | requiredTaobaoAuth = json['required_taobao_auth']; | ||||
skipIdentifier = json['skip_identifier']; | skipIdentifier = json['skip_identifier']; | ||||
@@ -155,11 +170,11 @@ class ListStyle extends SkipModel { | |||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
final Map<String, dynamic> data = super.toJson(); | final Map<String, dynamic> data = super.toJson(); | ||||
data['title'] = this.title; | |||||
data['img'] = this.img; | data['img'] = this.img; | ||||
data['title'] = this.title; | |||||
data['sub_title'] = this.subTitle; | data['sub_title'] = this.subTitle; | ||||
data['type_list_key'] = this.typeListKey; | |||||
data['right_icon'] = this.rightIcon; | data['right_icon'] = this.rightIcon; | ||||
data['type_list_key'] = this.typeListKey; | |||||
data['required_login'] = this.requiredLogin; | data['required_login'] = this.requiredLogin; | ||||
data['required_taobao_auth'] = this.requiredTaobaoAuth; | data['required_taobao_auth'] = this.requiredTaobaoAuth; | ||||
data['skip_identifier'] = this.skipIdentifier; | data['skip_identifier'] = this.skipIdentifier; | ||||
@@ -0,0 +1,5 @@ | |||||
export 'custom_notice_bloc.dart'; | |||||
export 'custom_notice_event.dart'; | |||||
export 'custom_notice_state.dart'; | |||||
export 'custom_notice_repository.dart'; | |||||
export '../model/custom_notice_model.dart'; |
@@ -0,0 +1,31 @@ | |||||
import 'dart:async'; | |||||
import 'package:bloc/bloc.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | |||||
import 'bloc.dart'; | |||||
class CustomNoticeBloc extends Bloc<CustomNoticeEvent, CustomNoticeState> { | |||||
CustomNoticeRepository repository; | |||||
CustomNoticeBloc({this.repository}); | |||||
@override | |||||
CustomNoticeState get initialState => CustomNoticeInitial(); | |||||
@override | |||||
Stream<CustomNoticeState> mapEventToState( | |||||
CustomNoticeEvent event, | |||||
) async* { | |||||
if(event is CustomNoticeInitEvent){ | |||||
yield* _mapInitEventToState(event); | |||||
} | |||||
} | |||||
/// 初始化 | |||||
Stream<CustomNoticeState> _mapInitEventToState(CustomNoticeInitEvent event) async* { | |||||
var parentData = await repository.fetchParentData(event); | |||||
if(!EmptyUtil.isEmpty(parentData)) | |||||
yield CustomNoticeLoadedState(model: parentData); | |||||
else | |||||
yield CustomNoticeErrorState(); | |||||
} | |||||
} |
@@ -1,16 +1,15 @@ | |||||
import 'package:equatable/equatable.dart'; | import 'package:equatable/equatable.dart'; | ||||
import 'bloc.dart'; | |||||
abstract class HomeNoticeEvent extends Equatable { | |||||
const HomeNoticeEvent(); | |||||
abstract class CustomNoticeEvent extends Equatable { | |||||
const CustomNoticeEvent(); | |||||
@override | @override | ||||
List<Object> get props => []; | List<Object> get props => []; | ||||
} | } | ||||
/// 初始化事件 | /// 初始化事件 | ||||
class HomeNoticeInitEvent extends HomeNoticeEvent{ | |||||
class CustomNoticeInitEvent extends CustomNoticeEvent{ | |||||
final Map<String, dynamic> model; | final Map<String, dynamic> model; | ||||
const HomeNoticeInitEvent({this.model}); | |||||
const CustomNoticeInitEvent({this.model}); | |||||
@override | @override | ||||
List<Object> get props => [this.model]; | List<Object> get props => [this.model]; | ||||
} | } |
@@ -0,0 +1,16 @@ | |||||
import 'dart:convert'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'bloc.dart'; | |||||
class CustomNoticeRepository { | |||||
/// 获取父页面的数据 | |||||
Future<CustomNoticeModel> fetchParentData(CustomNoticeInitEvent event) async { | |||||
try { | |||||
String jsonStr = event.model['data']; | |||||
return CustomNoticeModel.fromJson(jsonDecode(jsonStr)); | |||||
} catch (e) { | |||||
Logger.log(e); | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -0,0 +1,30 @@ | |||||
import 'package:equatable/equatable.dart'; | |||||
import 'package:zhiying_base_widget/widgets/custom/notice/model/custom_notice_model.dart'; | |||||
import 'bloc.dart'; | |||||
abstract class CustomNoticeState extends Equatable { | |||||
const CustomNoticeState(); | |||||
@override | |||||
List<Object> get props => []; | |||||
} | |||||
/// 初始化事件 | |||||
class CustomNoticeInitial extends CustomNoticeState { | |||||
@override | |||||
List<Object> get props => []; | |||||
} | |||||
/// 数据加载完毕 | |||||
class CustomNoticeLoadedState extends CustomNoticeState { | |||||
final CustomNoticeModel model; | |||||
const CustomNoticeLoadedState({this.model}); | |||||
@override | |||||
List<Object> get props => [this.model]; | |||||
} | |||||
/// 数据加载出错 | |||||
class CustomNoticeErrorState extends CustomNoticeState{ | |||||
} |
@@ -4,10 +4,10 @@ import 'package:flutter/material.dart'; | |||||
/// | /// | ||||
/// 公告的骨架屏 | /// 公告的骨架屏 | ||||
/// | /// | ||||
class HomeNoticeSkeleton extends StatelessWidget { | |||||
class CustomNoticeSkeleton extends StatelessWidget { | |||||
final Map<String, dynamic> map; | final Map<String, dynamic> map; | ||||
const HomeNoticeSkeleton({this.map}); | |||||
const CustomNoticeSkeleton({this.map}); | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { |
@@ -2,81 +2,84 @@ import 'dart:async'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_notice/bloc/home_notice_repository.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_notice/home_notice_sk.dart'; | |||||
import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_notice/model/home_notice_model.dart'; | |||||
import 'bloc/bloc.dart'; | import 'bloc/bloc.dart'; | ||||
import 'custom_notice_sk.dart'; | |||||
/// | /// | ||||
/// 公告滚动widget | /// 公告滚动widget | ||||
/// | /// | ||||
class HomeNoticeWidget extends StatelessWidget { | |||||
class CustomNoticeWidget extends StatelessWidget { | |||||
final Map<String, dynamic> model; | final Map<String, dynamic> model; | ||||
const HomeNoticeWidget(this.model); | |||||
const CustomNoticeWidget(this.model); | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return BlocProvider<HomeNoticeBloc>( | |||||
create: (_) => HomeNoticeBloc(repository: HomeNoticeRepository())..add(HomeNoticeInitEvent(model: model)), | |||||
child: HomeNoticeWidgetContianer(), | |||||
return BlocProvider<CustomNoticeBloc>( | |||||
create: (_) => CustomNoticeBloc(repository: CustomNoticeRepository())..add(CustomNoticeInitEvent(model: model)), | |||||
child: _CustomNoticeWidgetContainer(), | |||||
); | ); | ||||
} | } | ||||
} | } | ||||
class HomeNoticeWidgetContianer extends StatefulWidget { | |||||
class _CustomNoticeWidgetContainer extends StatefulWidget { | |||||
@override | @override | ||||
_HomeNoticeWidgetContianerState createState() => _HomeNoticeWidgetContianerState(); | |||||
_CustomNoticeWidgetContainerState createState() => _CustomNoticeWidgetContainerState(); | |||||
} | } | ||||
class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||||
class _CustomNoticeWidgetContainerState extends State<_CustomNoticeWidgetContainer> { | |||||
/// 子item点击事件 | /// 子item点击事件 | ||||
void _itemOnClick(HomeNoticeModel model) { | |||||
if(pageIndex == model.notices.length){ | |||||
void _itemOnClick(CustomNoticeModel model) { | |||||
if (pageIndex == model.listStyle.length) { | |||||
pageIndex = 0; | pageIndex = 0; | ||||
} | } | ||||
print('===== $pageIndex'); | print('===== $pageIndex'); | ||||
HomeNoticeNoticesModel item = model.notices[pageIndex]; | |||||
NoticeListStyle item = model.listStyle[pageIndex]; | |||||
_itemJump(item); | _itemJump(item); | ||||
} | } | ||||
/// 子item跳转 | /// 子item跳转 | ||||
void _itemJump(HomeNoticeNoticesModel model){ | |||||
print('${model?.notice_text}'); | |||||
void _itemJump(NoticeListStyle model) { | |||||
print('${model?.contentText}'); | |||||
RouterUtil.route(model, model.toJson(), context); | RouterUtil.route(model, model.toJson(), context); | ||||
} | } | ||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return BlocConsumer<HomeNoticeBloc, HomeNoticeState>( | |||||
return BlocConsumer<CustomNoticeBloc, CustomNoticeState>( | |||||
listener: (context, state) {}, | listener: (context, state) {}, | ||||
buildWhen: (prev, current) { | buildWhen: (prev, current) { | ||||
return true; | return true; | ||||
}, | }, | ||||
builder: (context, state) { | builder: (context, state) { | ||||
if (state is HomeNoticeLoadedState) { | |||||
if (state is CustomNoticeLoadedState) { | |||||
return _getMainWidget(state?.model); | return _getMainWidget(state?.model); | ||||
} | } | ||||
return HomeNoticeSkeleton(); | |||||
return CustomNoticeSkeleton(); | |||||
}, | }, | ||||
); | ); | ||||
} | } | ||||
/// 主体页面 | /// 主体页面 | ||||
Widget _getMainWidget(HomeNoticeModel model) { | |||||
Widget _getMainWidget(CustomNoticeModel model) { | |||||
return Container( | return Container( | ||||
width: double.infinity, | width: double.infinity, | ||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.only(bottomLeft: Radius.circular(7.5), bottomRight: Radius.circular(7.5))), | |||||
padding: const EdgeInsets.only(bottom: 7.5), | |||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex(model?.bgColor), | |||||
// color: Colors.orangeAccent, | |||||
borderRadius: BorderRadius.only( | |||||
topRight: Radius.circular(ParseUtil.stringParseDouble(model?.topRightRadius, defVal: 7.5)), | |||||
topLeft: Radius.circular(ParseUtil.stringParseDouble(model?.topLeftRadius, defVal: 7.5)), | |||||
bottomLeft: Radius.circular(ParseUtil.stringParseDouble(model?.bottomLeftRadius, defVal: 7.5)), | |||||
bottomRight: Radius.circular(ParseUtil.stringParseDouble(model?.bottomRightRadius, defVal: 7.5)), | |||||
)), | |||||
margin: EdgeInsets.only(top: ParseUtil.stringParseDouble(model?.topMargin)), | |||||
padding: EdgeInsets.symmetric(horizontal: ParseUtil.stringParseDouble(model?.leftRightMargin, defVal: 12.5), vertical: 7.5), | |||||
child: Container( | child: Container( | ||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.5), color: HexColor.fromHex(model?.bg_color)), | |||||
// color: Colors.cyan), | |||||
margin: const EdgeInsets.only(left: 12.5, right: 12.5), | |||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.5), color: HexColor.fromHex('#F6F6F6')), | |||||
padding: const EdgeInsets.only(top: 8, bottom: 8, left: 12, right: 8), | padding: const EdgeInsets.only(top: 8, bottom: 8, left: 12, right: 8), | ||||
// height: 30, | |||||
width: double.infinity, | width: double.infinity, | ||||
child: _getChildWidget(model), | child: _getChildWidget(model), | ||||
), | ), | ||||
@@ -85,7 +88,7 @@ class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||||
var pageIndex = 0; | var pageIndex = 0; | ||||
Widget _getChildWidget(HomeNoticeModel model) { | |||||
Widget _getChildWidget(CustomNoticeModel model) { | |||||
return GestureDetector( | return GestureDetector( | ||||
onTap: () => _itemOnClick(model), | onTap: () => _itemOnClick(model), | ||||
behavior: HitTestBehavior.opaque, | behavior: HitTestBehavior.opaque, | ||||
@@ -94,7 +97,7 @@ class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||||
/// 图片 | /// 图片 | ||||
// Container(width: 52, height: 13, color: Colors.red), | // Container(width: 52, height: 13, color: Colors.red), | ||||
CachedNetworkImage( | CachedNetworkImage( | ||||
imageUrl: model?.logo_img ?? '', | |||||
imageUrl: model?.appNameImg ?? '', | |||||
width: 52, | width: 52, | ||||
), | ), | ||||
const SizedBox(width: 14), | const SizedBox(width: 14), | ||||
@@ -107,10 +110,10 @@ class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||||
alignment: Alignment.centerLeft, | alignment: Alignment.centerLeft, | ||||
// color: Colors.yellowAccent, | // color: Colors.yellowAccent, | ||||
child: MarqueeWidget( | child: MarqueeWidget( | ||||
model?.notices?.length ?? 0, | |||||
model?.listStyle?.length ?? 0, | |||||
(BuildContext context, int index) { | (BuildContext context, int index) { | ||||
HomeNoticeNoticesModel item = model.notices[index]; | |||||
return Align(alignment: Alignment.centerLeft, child: Text('${item?.notice_text}' , style: TextStyle(color: HexColor.fromHex(model?.text_color), fontSize: 12))); | |||||
NoticeListStyle item = model.listStyle[index]; | |||||
return Align(alignment: Alignment.centerLeft, child: Text('${item?.contentText}', style: TextStyle(color: HexColor.fromHex(model?.textColor), fontSize: 12))); | |||||
}, | }, | ||||
onPageChanged: (index) => pageIndex = index, | onPageChanged: (index) => pageIndex = index, | ||||
), | ), | ||||
@@ -119,7 +122,7 @@ class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||||
const SizedBox(width: 14), | const SizedBox(width: 14), | ||||
/// 图片 | /// 图片 | ||||
CachedNetworkImage(imageUrl: model?.jump_img ?? '', height: 18), | |||||
CachedNetworkImage(imageUrl: model?.jumpImg ?? '', height: 18), | |||||
// Container( | // Container( | ||||
// width: 18, | // width: 18, | ||||
// height: 18, | // height: 18, |
@@ -0,0 +1,128 @@ | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class CustomNoticeModel { | |||||
String name; | |||||
String desc; | |||||
String moduleType; | |||||
String moduleKey; | |||||
String isTopMargin; | |||||
String isLeftRightMargin; | |||||
String isShow; | |||||
String topMargin; | |||||
String leftRightMargin; | |||||
String bgColor; | |||||
String topLeftRadius; | |||||
String topRightRadius; | |||||
String bottomLeftRadius; | |||||
String bottomRightRadius; | |||||
String textColor; | |||||
String appNameImg; | |||||
String jumpImg; | |||||
String bg_color; | |||||
List<NoticeListStyle> listStyle; | |||||
CustomNoticeModel( | |||||
{this.name, | |||||
this.desc, | |||||
this.moduleType, | |||||
this.moduleKey, | |||||
this.isTopMargin, | |||||
this.isLeftRightMargin, | |||||
this.isShow, | |||||
this.topMargin, | |||||
this.leftRightMargin, | |||||
this.bgColor, | |||||
this.topLeftRadius, | |||||
this.topRightRadius, | |||||
this.bottomLeftRadius, | |||||
this.bottomRightRadius, | |||||
this.textColor, | |||||
this.appNameImg, | |||||
this.jumpImg, | |||||
this.listStyle, | |||||
this.bg_color, | |||||
}); | |||||
CustomNoticeModel.fromJson(Map<String, dynamic> 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']; | |||||
bgColor = json['bg_color']; | |||||
topLeftRadius = json['top_left_radius']?.toString(); | |||||
topRightRadius = json['top_right_radius']?.toString(); | |||||
bottomLeftRadius = json['bottom_left_radius']?.toString(); | |||||
bottomRightRadius = json['bottom_right_radius']?.toString(); | |||||
textColor = json['text_color']; | |||||
appNameImg = json['app_name_img']; | |||||
jumpImg = json['jump_img']; | |||||
bg_color = json['bg_color']; | |||||
if (json['list_style'] != null) { | |||||
listStyle = new List<NoticeListStyle>(); | |||||
json['list_style'].forEach((v) { | |||||
listStyle.add(new NoticeListStyle.fromJson(v)); | |||||
}); | |||||
} | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
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; | |||||
data['bg_color'] = this.bgColor; | |||||
data['top_left_radius'] = this.topLeftRadius; | |||||
data['top_right_radius'] = this.topRightRadius; | |||||
data['bottom_left_radius'] = this.bottomLeftRadius; | |||||
data['bottom_right_radius'] = this.bottomRightRadius; | |||||
data['text_color'] = this.textColor; | |||||
data['app_name_img'] = this.appNameImg; | |||||
data['jump_img'] = this.jumpImg; | |||||
data['bg_color']= this.bg_color; | |||||
if (this.listStyle != null) { | |||||
data['list_style'] = this.listStyle.map((v) => v.toJson()).toList(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class NoticeListStyle extends SkipModel{ | |||||
String contentText; | |||||
String requiredLogin; | |||||
String requiredTaobaoAuth; | |||||
String skipIdentifier; | |||||
NoticeListStyle( | |||||
{this.contentText, | |||||
this.requiredLogin, | |||||
this.requiredTaobaoAuth, | |||||
this.skipIdentifier}); | |||||
NoticeListStyle.fromJson(Map<String, dynamic> json) { | |||||
super.fromJson(json); | |||||
contentText = json['content_text']; | |||||
requiredLogin = json['required_login']; | |||||
requiredTaobaoAuth = json['required_taobao_auth']; | |||||
skipIdentifier = json['skip_identifier']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = super.toJson(); | |||||
data['content_text'] = this.contentText; | |||||
data['required_login'] = this.requiredLogin; | |||||
data['required_taobao_auth'] = this.requiredTaobaoAuth; | |||||
data['skip_identifier'] = this.skipIdentifier; | |||||
return data; | |||||
} | |||||
} |
@@ -30,10 +30,17 @@ class CustomSearchWidget extends StatelessWidget { | |||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Container( | return Container( | ||||
width: double.infinity, | width: double.infinity, | ||||
padding: EdgeInsets.symmetric(horizontal: ParseUtil.stringParseDouble(model?.leftRightMargin, defVal: 12.5), vertical: 4), | |||||
margin: EdgeInsets.only(top: ParseUtil.stringParseDouble(model?.topMargin)), | |||||
decoration: BoxDecoration( | decoration: BoxDecoration( | ||||
color: HexColor.fromHex(model?.bgColor), | |||||
), | |||||
padding: const EdgeInsets.symmetric(horizontal: 12.5, vertical: 4), | |||||
color: HexColor.fromHex(model?.bgColor), | |||||
// color: Colors.blueAccent, | |||||
borderRadius: BorderRadius.only( | |||||
bottomRight: Radius.circular(ParseUtil.stringParseDouble(model?.bottomRightRadius)), | |||||
bottomLeft: Radius.circular(ParseUtil.stringParseDouble(model?.bottomLeftRadius)), | |||||
topLeft: Radius.circular(ParseUtil.stringParseDouble(model?.topLeftRadius)), | |||||
topRight: Radius.circular(ParseUtil.stringParseDouble(model?.topRightRadius)), | |||||
)), | |||||
child: _buildMainWidget(context)); | child: _buildMainWidget(context)); | ||||
} | } | ||||
@@ -10,6 +10,10 @@ class CustomSearchModel { | |||||
String isShow; | String isShow; | ||||
String topMargin; | String topMargin; | ||||
String leftRightMargin; | String leftRightMargin; | ||||
String topLeftRadius; | |||||
String topRightRadius; | |||||
String bottomLeftRadius; | |||||
String bottomRightRadius; | |||||
String bgColor; | String bgColor; | ||||
ListStyle listStyle; | ListStyle listStyle; | ||||
@@ -25,6 +29,10 @@ class CustomSearchModel { | |||||
this.leftRightMargin, | this.leftRightMargin, | ||||
this.bgColor, | this.bgColor, | ||||
this.listStyle, | this.listStyle, | ||||
this.topLeftRadius, | |||||
this.topRightRadius, | |||||
this.bottomLeftRadius, | |||||
this.bottomRightRadius, | |||||
}); | }); | ||||
CustomSearchModel.fromJson(Map<String, dynamic> json) { | CustomSearchModel.fromJson(Map<String, dynamic> json) { | ||||
@@ -38,6 +46,10 @@ class CustomSearchModel { | |||||
topMargin = json['top_margin']; | topMargin = json['top_margin']; | ||||
leftRightMargin = json['left_right_margin']; | leftRightMargin = json['left_right_margin']; | ||||
bgColor = json['bg_color']; | bgColor = json['bg_color']; | ||||
topLeftRadius = json['top_left_radius']; | |||||
topRightRadius = json['top_right_radius']; | |||||
bottomLeftRadius = json['bottom_left_radius']; | |||||
bottomRightRadius = json['bottom_right_radius']; | |||||
listStyle = json['list_style'] != null ? new ListStyle.fromJson(json['list_style']) : null; | listStyle = json['list_style'] != null ? new ListStyle.fromJson(json['list_style']) : null; | ||||
} | } | ||||
@@ -53,6 +65,10 @@ class CustomSearchModel { | |||||
data['top_margin'] = this.topMargin; | data['top_margin'] = this.topMargin; | ||||
data['left_right_margin'] = this.leftRightMargin; | data['left_right_margin'] = this.leftRightMargin; | ||||
data['bg_color'] = this.bgColor; | data['bg_color'] = this.bgColor; | ||||
data['top_left_radius'] = this.topLeftRadius; | |||||
data['top_right_radius'] = this.topRightRadius; | |||||
data['bottom_left_radius'] = this.bottomLeftRadius; | |||||
data['bottom_right_radius'] = this.bottomRightRadius; | |||||
if (this.listStyle != null) { | if (this.listStyle != null) { | ||||
data['list_style'] = this.listStyle.toJson(); | data['list_style'] = this.listStyle.toJson(); | ||||
} | } | ||||
@@ -99,50 +99,87 @@ class _CustomSlideBannerContainerState extends State<CustomSlideBannerContainer> | |||||
}); | }); | ||||
int size = datas?.indexCarouselList?.length ?? 0; | int size = datas?.indexCarouselList?.length ?? 0; | ||||
if (size == 0) return Container(); | |||||
// 根据宽高比获取到图片的高度 | |||||
// 左右边距 | |||||
double horizontalPadding = ParseUtil.stringParseDouble(datas?.leftRightMargin, defVal: 12.5); | |||||
// 上下的边距 | |||||
double verticalPadding = ParseUtil.stringParseDouble(datas?.topMargin, defVal: 10); | |||||
// 图片高度 | |||||
double imgHeight = (MediaQuery.of(context).size.width - horizontalPadding * 2) * ParseUtil.stringParseDouble(datas?.barWidthHeightRatio, defVal: 0.38); | |||||
// Logger.log('horizontalPadding = $horizontalPadding, verticalPadding = $verticalPadding, imgHeight = $imgHeight'); | |||||
return Container( | return Container( | ||||
margin: EdgeInsets.all(10), | |||||
width: double.infinity, | width: double.infinity, | ||||
height: 140, | |||||
height: imgHeight + verticalPadding * 2, | |||||
// color: Colors.green, | // color: Colors.green, | ||||
child: Swiper( | |||||
controller: _swiperController, | |||||
itemBuilder: (BuildContext context, int index) { | |||||
IndexCarouselList items = datas.indexCarouselList[index]; | |||||
return Container( | |||||
width: double.infinity, | |||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.5)), | |||||
child: ClipRRect( | |||||
borderRadius: BorderRadius.circular(7.5), | |||||
child: CachedNetworkImage( | |||||
imageUrl: items?.img ?? '', | |||||
fit: BoxFit.cover, | |||||
child: Stack( | |||||
children: <Widget>[ | |||||
Column( | |||||
children: <Widget>[ | |||||
Flexible( | |||||
flex: 6, | |||||
child: Container( | |||||
width: double.infinity, | |||||
height: double.infinity, | |||||
color: size > 1 ? HexColor.fromHex('#FFFF4242') : Colors.transparent, | |||||
// color: Colors.yellow, | |||||
), | |||||
), | ), | ||||
Flexible( | |||||
flex: 4, | |||||
child: Container( | |||||
height: double.infinity, | |||||
width: double.infinity, | |||||
color: size > 1 ? Colors.white : Colors.transparent, | |||||
// color: Colors.yellow, | |||||
), | |||||
) | |||||
], | |||||
), | |||||
Padding( | |||||
padding: EdgeInsets.symmetric(horizontal: horizontalPadding, vertical: verticalPadding), | |||||
child: Swiper( | |||||
controller: _swiperController, | |||||
itemBuilder: (BuildContext context, int index) { | |||||
IndexCarouselList items = datas.indexCarouselList[index]; | |||||
return Container( | |||||
width: double.infinity, | |||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.5)), | |||||
child: ClipRRect( | |||||
borderRadius: BorderRadius.circular(7.5), | |||||
child: CachedNetworkImage( | |||||
imageUrl: items?.img ?? '', | |||||
fit: BoxFit.cover, | |||||
), | |||||
), | |||||
); | |||||
}, | |||||
itemCount: size, | |||||
loop: size > 1, | |||||
autoplay: true, | |||||
onTap: (index) => _itemOnClick(datas.indexCarouselList[index]), | |||||
pagination: _getSwiperStyleByType(datas, size), | |||||
onIndexChanged: (index) { | |||||
// print('color = ${datas?.indexCarouselList[index]?.bgColor}'); | |||||
Provider.of<MainPageBgNotifier>(context, listen: false).switchBg(Container( | |||||
width: double.infinity, | |||||
height: 200, | |||||
color: HexColor.fromHex(datas?.indexCarouselList[index]?.bgColor), | |||||
)); | |||||
}, | |||||
), | ), | ||||
); | |||||
}, | |||||
itemCount: size, | |||||
loop: size > 1 , | |||||
autoplay: true, | |||||
onTap: (index) => _itemOnClick(datas.indexCarouselList[index]), | |||||
pagination: _getSwiperStyleByType(datas, size), | |||||
onIndexChanged: (index) { | |||||
// print('color = ${datas?.indexCarouselList[index]?.bgColor}'); | |||||
Provider.of<MainPageBgNotifier>(context, listen: false).switchBg(Container( | |||||
width: double.infinity, | |||||
height: 200, | |||||
color: HexColor.fromHex(datas?.indexCarouselList[index]?.bgColor), | |||||
)); | |||||
}, | |||||
), | |||||
], | |||||
), | ), | ||||
); | ); | ||||
} | } | ||||
/// 获取进度样式 | /// 获取进度样式 | ||||
SwiperPlugin _getSwiperStyleByType(CustomSlideBannerModel model, int pageCount) { | SwiperPlugin _getSwiperStyleByType(CustomSlideBannerModel model, int pageCount) { | ||||
// 一张图片就不滑动 | // 一张图片就不滑动 | ||||
if(pageCount <= 1){ | |||||
if (pageCount <= 1) { | |||||
return null; | return null; | ||||
} | } | ||||
@@ -134,7 +134,6 @@ class _GoodsDetailsSlideBannerContainerState | |||||
if ('1' != model.pagination_open) { | if ('1' != model.pagination_open) { | ||||
return null; | return null; | ||||
} | } | ||||
if ('type_number' == model.pagination) { | if ('type_number' == model.pagination) { | ||||
return _getNumswiperPlugin(pageCount, model.pagination_select_color, | return _getNumswiperPlugin(pageCount, model.pagination_select_color, | ||||
model.pagination_unselect_color); | model.pagination_unselect_color); | ||||
@@ -234,7 +233,7 @@ class _GoodsDetailsSlideBannerContainerState | |||||
SwiperPlugin _swiperCustomPaginationDito( | SwiperPlugin _swiperCustomPaginationDito( | ||||
int pageCount, String selectColor, String unselectColor) { | int pageCount, String selectColor, String unselectColor) { | ||||
return SwiperPagination( | return SwiperPagination( | ||||
margin: const EdgeInsets.only(), | |||||
margin: const EdgeInsets.only(bottom: 10), | |||||
builder: DotSwiperPaginationBuilder( | builder: DotSwiperPaginationBuilder( | ||||
color: HexColor.fromHex(unselectColor), | color: HexColor.fromHex(unselectColor), | ||||
activeColor: HexColor.fromHex(selectColor), | activeColor: HexColor.fromHex(selectColor), | ||||
@@ -9,12 +9,12 @@ import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class HomeAuth extends StatefulWidget { | class HomeAuth extends StatefulWidget { | ||||
final Map<String, dynamic> data; | final Map<String, dynamic> data; | ||||
Map<String, dynamic> _json; | Map<String, dynamic> _json; | ||||
HomeAuthModel _style; | |||||
HomeAuthModel _model; | |||||
HomeAuth(this.data, {Key key}) : super(key: key) { | HomeAuth(this.data, {Key key}) : super(key: key) { | ||||
String d = data['data']; | String d = data['data']; | ||||
_json = convert.jsonDecode(d); | _json = convert.jsonDecode(d); | ||||
_style = HomeAuthModel.fromJson(Map<String, dynamic>.from(_json)); | |||||
_model = HomeAuthModel.fromJson(Map<String, dynamic>.from(_json)); | |||||
} | } | ||||
@override | @override | ||||
@@ -52,13 +52,12 @@ class _HomeAuthState extends State<HomeAuth> { | |||||
width: double.infinity, | width: double.infinity, | ||||
margin: EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 4), | margin: EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 4), | ||||
decoration: BoxDecoration( | decoration: BoxDecoration( | ||||
color: HexColor.fromHex(widget._style?.taoaboTipBgColor ?? 'ffffff'), | |||||
color: HexColor.fromHex(!_isAuth ? widget._model?.listStyle?.before?.bgColor ?? 'ffffff' : widget?._model?.listStyle?.after?.bgColor ?? 'ffffff'), | |||||
borderRadius: BorderRadius.circular(17), | borderRadius: BorderRadius.circular(17), | ||||
boxShadow: [ | boxShadow: [ | ||||
BoxShadow( | BoxShadow( | ||||
offset: Offset(2, 1), //x,y轴 | offset: Offset(2, 1), //x,y轴 | ||||
color: HexColor.fromHex( | |||||
widget._style?.taoaboTipShadowColor ?? '767676') | |||||
color: HexColor.fromHex('767676') | |||||
.withAlpha(70), //投影颜色 | .withAlpha(70), //投影颜色 | ||||
blurRadius: 5 //投影距离 | blurRadius: 5 //投影距离 | ||||
) | ) | ||||
@@ -70,19 +69,19 @@ class _HomeAuthState extends State<HomeAuth> { | |||||
width: 20, | width: 20, | ||||
height: 20, | height: 20, | ||||
child: CachedNetworkImage( | child: CachedNetworkImage( | ||||
imageUrl: widget._style.taobaoAuthIcon, | |||||
imageUrl: !_isAuth ? widget._model?.listStyle?.before?.auditImg ?? '' : widget?._model?.listStyle?.after?.auditImg ?? '', | |||||
fit: BoxFit.contain, | fit: BoxFit.contain, | ||||
), | ), | ||||
), | ), | ||||
Expanded( | Expanded( | ||||
child: Text( | child: Text( | ||||
widget._style?.taoaboTipText ?? '', | |||||
!_isAuth ? widget._model?.listStyle?.before?.contentText ?? '' : widget?._model?.listStyle?.after?.contentText ?? '', | |||||
maxLines: 1, | maxLines: 1, | ||||
style: TextStyle( | style: TextStyle( | ||||
fontSize: 12, | fontSize: 12, | ||||
fontWeight: FontWeight.bold, | fontWeight: FontWeight.bold, | ||||
color: HexColor.fromHex( | color: HexColor.fromHex( | ||||
widget._style?.taoaboTipTextColor ?? '333333'), | |||||
!_isAuth ? widget._model?.listStyle?.before?.contentTextColor ?? '333333' : widget?._model?.listStyle?.after?.contentTextColor ?? '333333'), | |||||
), | ), | ||||
), | ), | ||||
), | ), | ||||
@@ -92,14 +91,14 @@ class _HomeAuthState extends State<HomeAuth> { | |||||
margin: EdgeInsets.only(left: 8, right: 8), | margin: EdgeInsets.only(left: 8, right: 8), | ||||
decoration: BoxDecoration( | decoration: BoxDecoration( | ||||
color: HexColor.fromHex( | color: HexColor.fromHex( | ||||
widget._style?.taoaboTipBtnBgColor ?? 'FF4242'), | |||||
!_isAuth ? widget._model?.listStyle?.before?.btnBgColor ?? 'FF4242' : widget?._model?.listStyle?.after?.btnBgColor ?? 'FF4242' ), | |||||
borderRadius: BorderRadius.circular(20)), | borderRadius: BorderRadius.circular(20)), | ||||
child: Text( | child: Text( | ||||
widget._style?.taoaboTipBtnText ?? '', | |||||
!_isAuth ? widget._model?.listStyle?.before?.btnText ?? '' : widget?._model?.listStyle?.after?.btnText ?? '', | |||||
style: TextStyle( | style: TextStyle( | ||||
fontSize: 12, | fontSize: 12, | ||||
color: HexColor.fromHex( | color: HexColor.fromHex( | ||||
widget._style?.taoaboTipBtnTextColor ?? 'ffffff'), | |||||
!_isAuth ? widget._model?.listStyle?.before?.btnTextColor ?? 'ffffff' : widget?._model?.listStyle?.after?.btnTextColor ?? ''), | |||||
), | ), | ||||
), | ), | ||||
), | ), | ||||
@@ -1,45 +1,157 @@ | |||||
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 HomeAuthModel { | class HomeAuthModel { | ||||
String taobaoAuthIcon; | |||||
String taoaboTipBgColor; | |||||
String taoaboTipShadowColor; | |||||
String taoaboTipTextColor; | |||||
String taoaboTipText; | |||||
String taoaboTipBtnTextColor; | |||||
String taoaboTipBtnBgColor; | |||||
String taoaboTipBtnText; | |||||
String name; | |||||
String desc; | |||||
String moduleType; | |||||
String moduleKey; | |||||
String isTopMargin; | |||||
String isLeftRightMargin; | |||||
String isShow; | |||||
String topMargin; | |||||
String leftRightMargin; | |||||
String topLeftRadius; | |||||
String topRightRadius; | |||||
String bottomLeftRadius; | |||||
String bottomRightRadius; | |||||
String isAuditAfterShow; | |||||
ListStyle listStyle; | |||||
HomeAuthModel( | HomeAuthModel( | ||||
{this.taobaoAuthIcon, | |||||
this.taoaboTipBgColor, | |||||
this.taoaboTipShadowColor, | |||||
this.taoaboTipTextColor, | |||||
this.taoaboTipText, | |||||
this.taoaboTipBtnTextColor, | |||||
this.taoaboTipBtnBgColor, | |||||
this.taoaboTipBtnText}); | |||||
{this.name, | |||||
this.desc, | |||||
this.moduleType, | |||||
this.moduleKey, | |||||
this.isTopMargin, | |||||
this.isLeftRightMargin, | |||||
this.isShow, | |||||
this.topMargin, | |||||
this.leftRightMargin, | |||||
this.topLeftRadius, | |||||
this.topRightRadius, | |||||
this.bottomLeftRadius, | |||||
this.bottomRightRadius, | |||||
this.isAuditAfterShow, | |||||
this.listStyle}); | |||||
HomeAuthModel.fromJson(Map<String, dynamic> json) { | HomeAuthModel.fromJson(Map<String, dynamic> json) { | ||||
taobaoAuthIcon = json['taobao_auth_icon']; | |||||
taoaboTipBgColor = json['taoabo_tip_bg_color']; | |||||
taoaboTipShadowColor = json['taoabo_tip_shadow_color']; | |||||
taoaboTipTextColor = json['taoabo_tip_text_color']; | |||||
taoaboTipText = json['taoabo_tip_text']; | |||||
taoaboTipBtnTextColor = json['taoabo_tip_btn_text_color']; | |||||
taoaboTipBtnBgColor = json['taoabo_tip_btn_bg_color']; | |||||
taoaboTipBtnText = json['taoabo_tip_btn_text']; | |||||
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']; | |||||
topLeftRadius = json['top_left_radius']; | |||||
topRightRadius = json['top_right_radius']; | |||||
bottomLeftRadius = json['bottom_left_radius']; | |||||
bottomRightRadius = json['bottom_right_radius']; | |||||
isAuditAfterShow = json['is_audit_after_show']; | |||||
listStyle = json['list_style'] != null | |||||
? new ListStyle.fromJson(json['list_style']) | |||||
: null; | |||||
} | } | ||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | final Map<String, dynamic> data = new Map<String, dynamic>(); | ||||
data['taobao_auth_icon'] = this.taobaoAuthIcon; | |||||
data['taoabo_tip_bg_color'] = this.taoaboTipBgColor; | |||||
data['taoabo_tip_shadow_color'] = this.taoaboTipShadowColor; | |||||
data['taoabo_tip_text_color'] = this.taoaboTipTextColor; | |||||
data['taoabo_tip_text'] = this.taoaboTipText; | |||||
data['taoabo_tip_btn_text_color'] = this.taoaboTipBtnTextColor; | |||||
data['taoabo_tip_btn_bg_color'] = this.taoaboTipBtnBgColor; | |||||
data['taoabo_tip_btn_text'] = this.taoaboTipBtnText; | |||||
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; | |||||
data['top_left_radius'] = this.topLeftRadius; | |||||
data['top_right_radius'] = this.topRightRadius; | |||||
data['bottom_left_radius'] = this.bottomLeftRadius; | |||||
data['bottom_right_radius'] = this.bottomRightRadius; | |||||
data['is_audit_after_show'] = this.isAuditAfterShow; | |||||
if (this.listStyle != null) { | |||||
data['list_style'] = this.listStyle.toJson(); | |||||
} | |||||
return data; | return data; | ||||
} | } | ||||
} | } | ||||
class ListStyle { | |||||
Before before; | |||||
Before after; | |||||
ListStyle({this.before, this.after}); | |||||
ListStyle.fromJson(Map<String, dynamic> json) { | |||||
before = | |||||
json['before'] != null ? new Before.fromJson(json['before']) : null; | |||||
after = json['after'] != null ? new Before.fromJson(json['after']) : null; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
if (this.before != null) { | |||||
data['before'] = this.before.toJson(); | |||||
} | |||||
if (this.after != null) { | |||||
data['after'] = this.after.toJson(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class Before extends SkipModel{ | |||||
String auditImg; | |||||
String contentText; | |||||
String contentTextColor; | |||||
String bgColor; | |||||
String btnText; | |||||
String btnTextColor; | |||||
String btnBgColor; | |||||
String requiredLogin; | |||||
String requiredTaobaoAuth; | |||||
String skipIdentifier; | |||||
Before( | |||||
{this.auditImg, | |||||
this.contentText, | |||||
this.contentTextColor, | |||||
this.bgColor, | |||||
this.btnText, | |||||
this.btnTextColor, | |||||
this.btnBgColor, | |||||
this.requiredLogin, | |||||
this.requiredTaobaoAuth, | |||||
this.skipIdentifier}); | |||||
Before.fromJson(Map<String, dynamic> json) { | |||||
super.fromJson(json); | |||||
auditImg = json['audit_img']; | |||||
contentText = json['content_text']; | |||||
contentTextColor = json['content_text_color']; | |||||
bgColor = json['bg_color']; | |||||
btnText = json['btn_text']; | |||||
btnTextColor = json['btn_text_color']; | |||||
btnBgColor = json['btn_bg_color']; | |||||
requiredLogin = json['required_login']; | |||||
requiredTaobaoAuth = json['required_taobao_auth']; | |||||
skipIdentifier = json['skip_identifier']; | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = super.toJson(); | |||||
data['audit_img'] = this.auditImg; | |||||
data['content_text'] = this.contentText; | |||||
data['content_text_color'] = this.contentTextColor; | |||||
data['bg_color'] = this.bgColor; | |||||
data['btn_text'] = this.btnText; | |||||
data['btn_text_color'] = this.btnTextColor; | |||||
data['btn_bg_color'] = this.btnBgColor; | |||||
data['required_login'] = this.requiredLogin; | |||||
data['required_taobao_auth'] = this.requiredTaobaoAuth; | |||||
data['skip_identifier'] = this.skipIdentifier; | |||||
return data; | |||||
} | |||||
} |
@@ -1,14 +1,15 @@ | |||||
import 'dart:async'; | import 'dart:async'; | ||||
import 'package:zhiying_base_widget/widgets/custom/goods/category_goods/category_goods_callback.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_model.dart'; | import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_model.dart'; | ||||
import 'package:zhiying_comm/util/base_bloc.dart'; | import 'package:zhiying_comm/util/base_bloc.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
class HomeGoodsBloc extends BlocBase { | |||||
class HomeGoodsBloc extends BlocBase implements CategoryGoodsOnClickCallBack{ | |||||
List<HomeGoodsModel> _goods = List(); | List<HomeGoodsModel> _goods = List(); | ||||
String _provider = ''; | String _provider = ''; | ||||
String providerss = ''; | |||||
int _page = 1; | int _page = 1; | ||||
StreamController<List<HomeGoodsModel>> _goodsController = StreamController<List<HomeGoodsModel>>(); | StreamController<List<HomeGoodsModel>> _goodsController = StreamController<List<HomeGoodsModel>>(); | ||||
@@ -67,4 +68,12 @@ class HomeGoodsBloc extends BlocBase { | |||||
_goodsController.add(_goods); | _goodsController.add(_goods); | ||||
}); | }); | ||||
} | } | ||||
@override | |||||
void onTap(int index, String providerType) { | |||||
Logger.error('index = $index, providerType = $providerType'); | |||||
_provider = providerType; | |||||
loadMore(providerType); | |||||
} | |||||
} | } |
@@ -1,3 +1,5 @@ | |||||
import 'dart:convert'; | |||||
import 'package:event_bus/event_bus.dart'; | import 'package:event_bus/event_bus.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_goods/bloc/home_goods_header_bloc.dart'; | import 'package:zhiying_base_widget/widgets/home/home_goods/bloc/home_goods_header_bloc.dart'; | ||||
@@ -7,22 +9,17 @@ import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
class GoodsListCreater extends WidgetCreater { | class GoodsListCreater extends WidgetCreater { | ||||
final EventBus _eventBus = EventBus(); | |||||
@override | @override | ||||
List<Widget> createWidgets(Map<String, dynamic> model) { | List<Widget> createWidgets(Map<String, dynamic> model) { | ||||
print('创建商品列表'); | print('创建商品列表'); | ||||
Widget _widget = BlocProvider<HomeGoodsHeaderBloc>( | |||||
bloc: HomeGoodsHeaderBloc(), | |||||
child: HomeGoodsHeader(model, _eventBus), | |||||
); | |||||
// final EventBus _eventBus = EventBus(); | |||||
final EventBus _eventBus = model['eventBus']; | |||||
Widget _widget = BlocProvider<HomeGoodsHeaderBloc>(bloc: HomeGoodsHeaderBloc(), child: HomeGoodsHeader(model, _eventBus)); | |||||
Map<String, dynamic> json = jsonDecode(model['data']); | |||||
return [ | return [ | ||||
SliverPersistentHeader( | |||||
pinned: true, | |||||
floating: false, | |||||
delegate: HomeGoodsHeaderDelegate(_widget), | |||||
), | |||||
SliverToBoxAdapter(child: Container(margin: EdgeInsets.only(top: ParseUtil.stringParseDouble(null != json ? json['top_margin'] : '0')))), | |||||
SliverPersistentHeader(pinned: true, floating: false, delegate: HomeGoodsHeaderDelegate(_widget)), | |||||
HomeGoods(model, eventBus: _eventBus), | HomeGoods(model, eventBus: _eventBus), | ||||
]; | ]; | ||||
} | } | ||||
@@ -109,6 +109,7 @@ class _HomeGoodsHeaderState extends State<_HomeGoodsHeader> | |||||
width: double.infinity, | width: double.infinity, | ||||
height: double.infinity, | height: double.infinity, | ||||
color: Color(0xfff9f9f9), | color: Color(0xfff9f9f9), | ||||
// color: Colors.yellow, | |||||
child: TabBar( | child: TabBar( | ||||
indicatorColor: Colors.transparent, | indicatorColor: Colors.transparent, | ||||
controller: _tabController, | controller: _tabController, | ||||
@@ -1,3 +0,0 @@ | |||||
export 'home_notice_bloc.dart'; | |||||
export 'home_notice_event.dart'; | |||||
export 'home_notice_state.dart'; |
@@ -1,32 +0,0 @@ | |||||
import 'dart:async'; | |||||
import 'package:bloc/bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_notice/bloc/home_notice_repository.dart'; | |||||
import 'package:zhiying_comm/util/empty_util.dart'; | |||||
import 'bloc.dart'; | |||||
class HomeNoticeBloc extends Bloc<HomeNoticeEvent, HomeNoticeState> { | |||||
HomeNoticeRepository repository; | |||||
HomeNoticeBloc({this.repository}); | |||||
@override | |||||
HomeNoticeState get initialState => HomeNoticeInitial(); | |||||
@override | |||||
Stream<HomeNoticeState> mapEventToState( | |||||
HomeNoticeEvent event, | |||||
) async* { | |||||
if(event is HomeNoticeInitEvent){ | |||||
yield* _mapInitEventToState(event); | |||||
} | |||||
} | |||||
/// 初始化 | |||||
Stream<HomeNoticeState> _mapInitEventToState(HomeNoticeInitEvent event) async* { | |||||
var parentData = await repository.fetchParentData(event); | |||||
if(!EmptyUtil.isEmpty(parentData)) | |||||
yield HomeNoticeLoadedState(model: parentData); | |||||
else | |||||
yield HomeNoticeErrorState(); | |||||
} | |||||
} |
@@ -1,18 +0,0 @@ | |||||
import 'dart:convert'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_notice/bloc/bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_notice/model/home_notice_model.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class HomeNoticeRepository { | |||||
/// 获取父页面的数据 | |||||
Future<HomeNoticeModel> fetchParentData(HomeNoticeInitEvent event) async { | |||||
try { | |||||
String jsonStr = event.model['data']; | |||||
return HomeNoticeModel.fromJson(jsonDecode(jsonStr)); | |||||
} catch (e) { | |||||
Logger.log(e); | |||||
} | |||||
return null; | |||||
} | |||||
} |
@@ -1,30 +0,0 @@ | |||||
import 'package:equatable/equatable.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_notice/model/home_notice_model.dart'; | |||||
import 'bloc.dart'; | |||||
abstract class HomeNoticeState extends Equatable { | |||||
const HomeNoticeState(); | |||||
@override | |||||
List<Object> get props => []; | |||||
} | |||||
/// 初始化事件 | |||||
class HomeNoticeInitial extends HomeNoticeState { | |||||
@override | |||||
List<Object> get props => []; | |||||
} | |||||
/// 数据加载完毕 | |||||
class HomeNoticeLoadedState extends HomeNoticeState { | |||||
final HomeNoticeModel model; | |||||
const HomeNoticeLoadedState({this.model}); | |||||
@override | |||||
List<Object> get props => [this.model]; | |||||
} | |||||
/// 数据加载出错 | |||||
class HomeNoticeErrorState extends HomeNoticeState{ | |||||
} |
@@ -1,60 +0,0 @@ | |||||
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 HomeNoticeModel { | |||||
String logo_img; | |||||
String jump_img; | |||||
String bg_color; | |||||
String text_color; | |||||
String duration_time; | |||||
List<HomeNoticeNoticesModel> notices; | |||||
HomeNoticeModel({this.notices, this.logo_img, this.jump_img, this.bg_color, this.text_color, this.duration_time}); | |||||
factory HomeNoticeModel.fromJson(Map<String, dynamic> json) { | |||||
return HomeNoticeModel( | |||||
logo_img: json['logo_img']?.toString(), | |||||
jump_img: json['jump_img']?.toString(), | |||||
bg_color: json['bg_color']?.toString(), | |||||
text_color: json['text_color']?.toString(), | |||||
duration_time: json['duration_time']?.toString(), | |||||
notices: json['notices'] != null ? (json['notices'] as List).map((i) => HomeNoticeNoticesModel.fromJson(i)).toList() : null, | |||||
); | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['duration_time'] = this.duration_time; | |||||
data['text_color'] = this.text_color; | |||||
data['bg_color'] = this.bg_color; | |||||
data['jump_img'] = this.jump_img; | |||||
data['logo_img'] = this.logo_img; | |||||
if (this.notices != null) { | |||||
data['notices'] = this.notices.map((v) => v.toJson()).toList(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class HomeNoticeNoticesModel extends SkipModel{ | |||||
String notice_text; | |||||
String skip_identifier; | |||||
HomeNoticeNoticesModel({this.notice_text, this.skip_identifier}); | |||||
HomeNoticeNoticesModel.fromJson(Map<String, dynamic> json) { | |||||
super.fromJson(json); | |||||
notice_text = json['notice_text']?.toString(); | |||||
skip_identifier = json['skip_identifier']?.toString(); | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
Map<String, dynamic> data = super.toJson(); | |||||
data['img'] = this.notice_text; | |||||
data['skip_identifier'] = this.skip_identifier; | |||||
return data; | |||||
} | |||||
} |
@@ -1,12 +1,21 @@ | |||||
import 'dart:convert'; | |||||
import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:provider/provider.dart'; | import 'package:provider/provider.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart'; | import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart'; | ||||
class MineNavBg extends StatefulWidget { | class MineNavBg extends StatefulWidget { | ||||
final Map<String, dynamic> data; | final Map<String, dynamic> data; | ||||
const MineNavBg(this.data, {Key key}) : super(key: key); | |||||
Map<String, dynamic> model; | |||||
MineNavBg(this.data, {Key key}) : super(key: key){ | |||||
try{ | |||||
model = jsonDecode(data['data']); | |||||
} catch(e,s){ | |||||
Logger.error(e,s); | |||||
} | |||||
} | |||||
@override | @override | ||||
_MineNavBgState createState() => _MineNavBgState(); | _MineNavBgState createState() => _MineNavBgState(); | ||||
@@ -20,13 +29,13 @@ class _MineNavBgState extends State<MineNavBg> { | |||||
void _updateBg() { | void _updateBg() { | ||||
final double statusBarHeight = MediaQuery.of(context).padding.top; | final double statusBarHeight = MediaQuery.of(context).padding.top; | ||||
if (widget.data.containsKey('img')) { | |||||
if (widget.model.containsKey('img')) { | |||||
Provider.of<MainPageBgNotifier>(context, listen: false).switchBg( | Provider.of<MainPageBgNotifier>(context, listen: false).switchBg( | ||||
Container( | Container( | ||||
width: double.infinity, | width: double.infinity, | ||||
height: statusBarHeight + 250, | height: statusBarHeight + 250, | ||||
child: CachedNetworkImage( | child: CachedNetworkImage( | ||||
imageUrl: widget.data['img'], | |||||
imageUrl: widget.model['img'], | |||||
fit: BoxFit.fitHeight, | fit: BoxFit.fitHeight, | ||||
), | ), | ||||
), | ), | ||||
@@ -0,0 +1,34 @@ | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:loading_indicator/loading_indicator.dart'; | |||||
import 'package:pull_to_refresh/pull_to_refresh.dart'; | |||||
class RefreshGifHeader extends StatelessWidget { | |||||
final double offsetY; | |||||
// final double _height = 50; | |||||
const RefreshGifHeader({Key key, this.offsetY = 0}) : super(key: key); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
// double top = MediaQueryData.fromWindow(window).padding.top; | |||||
return CustomHeader( | |||||
// height: _height, | |||||
builder: (BuildContext context, RefreshStatus mode) { | |||||
return Transform.translate( | |||||
offset: Offset(0, offsetY), | |||||
child: Center( | |||||
child: Container( | |||||
// color: Colors.white, | |||||
alignment: Alignment.center, | |||||
height: 50, | |||||
child: Image.asset( | |||||
'assets/images/loading/loading.gif', | |||||
package: 'zhiying_base_widget', | |||||
), | |||||
), | |||||
), | |||||
); | |||||
}, | |||||
); | |||||
} | |||||
} |
@@ -68,6 +68,7 @@ flutter: | |||||
- assets/images/launch_image/launch_image.png | - assets/images/launch_image/launch_image.png | ||||
- assets/images/empty/empty.png | - assets/images/empty/empty.png | ||||
- assets/images/qrcode/default_qrcode.png | - assets/images/qrcode/default_qrcode.png | ||||
- assets/images/loading/loading.gif | |||||
# | # | ||||
# For details regarding assets in packages, see | # For details regarding assets in packages, see | ||||
# https://flutter.dev/assets-and-images/#from-packages | # https://flutter.dev/assets-and-images/#from-packages | ||||