@@ -55,7 +55,11 @@ class CustomPageBloc extends Bloc<CustomPageEvent, CustomPageState> { | |||
if (!EmptyUtil.isEmpty(result) && result is List) { | |||
yield CustomPageLoadedState(model: result); | |||
} 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:pull_to_refresh/pull_to_refresh.dart'; | |||
import 'package:provider/provider.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/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_header/refresh_gif_header.dart'; | |||
import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_header.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'bloc/custom_item_page_bloc.dart'; | |||
@@ -60,6 +63,8 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit | |||
ScrollController _controller; | |||
RefreshController _refreshController; | |||
final EventBus _eventBus = EventBus(); | |||
/// 回到顶点 | |||
void _scrollTop() { | |||
@@ -145,18 +150,26 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit | |||
return MediaQuery.removePadding( | |||
context: context, | |||
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 = []; | |||
for (int i = 0; i < datas.length; 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( | |||
item.modName, | |||
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; | |||
} | |||
@@ -207,4 +227,22 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit | |||
Widget _buildSkeletonWidget() { | |||
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) { | |||
return Stack( | |||
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( | |||
appBar: _buildAppbar(model?.first), | |||
backgroundColor: Colors.transparent, | |||
backgroundColor: HexColor.fromHex('#F9F9F9'), | |||
// floatingActionButton: _buildFloatWidget(), | |||
floatingActionButtonLocation: _CustomFloatingActionButtonLocation(FloatingActionButtonLocation.endFloat, 0, -100), | |||
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])); | |||
} | |||
// 没有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; | |||
@@ -260,7 +240,7 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single | |||
} catch (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; | |||
return AppBar( | |||
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( | |||
height: 40, | |||
width: double.infinity, | |||
// color: HexColor.fromHex('#FFFFFF'), | |||
color: HexColor.fromHex(data['bg_color']), | |||
child: TabBar( | |||
controller: _tabController, | |||
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), | |||
unselectedLabelColor: HexColor.fromHex('#999999'), | |||
unselectedLabelColor: HexColor.fromHex(data['text_color'] ?? '#999999'), | |||
unselectedLabelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), | |||
indicatorSize: TabBarIndicatorSize.label, | |||
indicator: MaterialIndicator( | |||
color: HexColor.fromHex('#FF4242'), | |||
color: HexColor.fromHex(data['choose_color'] ?? '#FF4242'), | |||
bottomLeftRadius: 1.25, | |||
topLeftRadius: 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/withdraw_page/withdraw_page.dart'; | |||
import 'package:zhiying_base_widget/widgets/custom/banner/custom_banner_widget.dart'; | |||
import 'package:zhiying_base_widget/widgets/custom/goods/custom_goods_widget.dart'; | |||
import 'package:zhiying_base_widget/widgets/custom/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/notice/custom_notice_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/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/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_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_sreach/home_sreach_creater.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/recommend/goods_detail_commend_creater.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/search/history_tag/search_history_tag.dart'; | |||
import 'widgets/search/hot_tag/search_hot_tag_widget.dart'; | |||
@@ -136,19 +136,19 @@ class BaseWidgetRegister { | |||
// 缓存可能用到的数据,预加载 | |||
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; | |||
}); | |||
@@ -247,7 +247,7 @@ class BaseWidgetRegister { | |||
// 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 | |||
WidgetFactory.regist('index_banner_one', HomeBannerCreater()); | |||
@@ -374,5 +374,9 @@ class BaseWidgetRegister { | |||
WidgetFactory.regist('banner', DefaultWidgetCreater((model) => CustomBannerWidget(model))); | |||
// 商品列表 | |||
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); | |||
} | |||
double _convert(String val) { | |||
double result = 0.0; | |||
try { | |||
result = double.parse(val); | |||
} catch (e) { | |||
result = 0; | |||
} | |||
return result; | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
/// 空视图 | |||
@@ -44,9 +34,17 @@ class CustomBannerWidget extends StatelessWidget { | |||
return Container( | |||
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), | |||
); | |||
} | |||
@@ -196,11 +194,9 @@ class CustomBannerWidget extends StatelessWidget { | |||
behavior: HitTestBehavior.opaque, | |||
onTap: () => _itemOnClick(context, e), | |||
child: Container( | |||
height: double.infinity, | |||
width: double.infinity, | |||
child: CachedNetworkImage( | |||
imageUrl: e?.img ?? '', | |||
fit: BoxFit.fitWidth, | |||
)), | |||
), | |||
)) | |||
@@ -11,11 +11,30 @@ class CustomBannerModel { | |||
String isShow; | |||
String topMargin; | |||
String leftRightMargin; | |||
String topLeftRadius; | |||
String topRightRadius; | |||
String bottomLeftRadius; | |||
String bottomRightRadius; | |||
List<CustomBannerListStyle> listStyle; | |||
int moduleKeyId; | |||
CustomBannerModel( | |||
{this.name, this.desc, this.moduleType, this.moduleKey, this.isTopMargin, this.isLeftRightMargin, this.isShow, this.topMargin, this.leftRightMargin, this.listStyle, this.moduleKeyId}); | |||
CustomBannerModel({ | |||
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) { | |||
name = json['name']; | |||
@@ -27,6 +46,10 @@ class CustomBannerModel { | |||
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']; | |||
if (json['list_style'] != null) { | |||
listStyle = new List<CustomBannerListStyle>(); | |||
json['list_style'].forEach((v) { | |||
@@ -47,6 +70,10 @@ class CustomBannerModel { | |||
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; | |||
if (this.listStyle != null) { | |||
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 img; | |||
String locationType; | |||
@@ -79,7 +106,7 @@ class CustomBannerListStyle extends SkipModel{ | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = super.toJson(); | |||
data['name'] = this.name; | |||
data['img'] = this.img; | |||
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_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 | |||
List<Widget> createWidgets(Map<String, dynamic> model) { | |||
Map<String, dynamic> json = jsonDecode(model['data']); | |||
// 有Tab头部的商品列表 | |||
if (!EmptyUtil.isEmpty(json['recommend_list'])) { | |||
// creater = CategoryGoodsListCreater2(); | |||
// creater = CategoryGoodsListCreater(); | |||
creater = GoodsListCreater(); | |||
} else { | |||
// 没有Tab头部的商品列表 | |||
creater = GoodsDetailCommendCreater(); | |||
} | |||
return creater?.createWidgets(model) ?? SliverToBoxAdapter(child: Container()); |
@@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:flutter_bloc/flutter_bloc.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:cached_network_image/cached_network_image.dart'; | |||
import 'custom_quick_entry_sk.dart'; | |||
@@ -73,7 +74,7 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||
}, | |||
); | |||
} | |||
Widget _getMainWidget(CustomQuickEntryModel model) { | |||
// 数据总数 | |||
int totalDataSize = model?.listStyle?.length ?? 0; | |||
@@ -82,7 +83,7 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||
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; | |||
@@ -113,38 +114,126 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||
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( | |||
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( | |||
margin: EdgeInsets.only(top: 15, bottom: totalPage > 1 ? 15 : 0), | |||
margin: EdgeInsets.only(top: !hasCategory ? 15 : 0, 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, | |||
// color: HexColor.fromHex(widget?.model['bg_color']), | |||
child: Column( | |||
children: <Widget>[ | |||
Container( | |||
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'*/) { | |||
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'; | |||
class CustomQuickEntryModel { | |||
@@ -11,64 +12,77 @@ class CustomQuickEntryModel { | |||
String isShow; | |||
String topMargin; | |||
String leftRightMargin; | |||
String topLeftRadius; | |||
String topRightRadius; | |||
String bottomLeftRadius; | |||
String bottomRightRadius; | |||
String rowSize; | |||
String columnSize; | |||
String isShowSubTitle; | |||
String bgColor; | |||
String paginationSelectColor; | |||
String paginationUnselectColor; | |||
String isShowTitle; | |||
String isShowSubTitle; | |||
String isShowCornerIcon; | |||
String isShowCategory; | |||
String paginationSelectColor; | |||
String paginationUnselectColor; | |||
List<ListStyle> listStyle; | |||
List<TypeList> typeList; | |||
int moduleKeyId; | |||
String titleColor; | |||
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) { | |||
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(); | |||
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) { | |||
listStyle = new List<ListStyle>(); | |||
json['list_style'].forEach((v) { | |||
@@ -81,10 +95,9 @@ class CustomQuickEntryModel { | |||
typeList.add(new TypeList.fromJson(v)); | |||
}); | |||
} | |||
moduleKeyId = json['module_key_id']; | |||
titleColor = json['title_color']; | |||
subTitleColor = json['sub_title_color']; | |||
isShowTitle = '1'; | |||
columSize = json['colum_size']?.toString(); | |||
} | |||
Map<String, dynamic> toJson() { | |||
@@ -99,55 +112,57 @@ class CustomQuickEntryModel { | |||
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['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_corner_icon'] = this.isShowCornerIcon; | |||
data['is_show_category'] = this.isShowCategory; | |||
data['pagination_select_color'] = this.paginationSelectColor; | |||
data['pagination_unselect_color'] = this.paginationUnselectColor; | |||
if (this.listStyle != null) { | |||
data['list_style'] = this.listStyle.map((v) => v.toJson()).toList(); | |||
} | |||
if (this.typeList != null) { | |||
data['type_list'] = this.typeList.map((v) => v.toJson()).toList(); | |||
} | |||
data['module_key_id'] = this.moduleKeyId; | |||
data['title_color'] = this.titleColor; | |||
data['sub_title_color'] = this.subTitleColor; | |||
data['is_show_title'] = this.isShowTitle; | |||
data['colum_size'] = this.columSize; | |||
return data; | |||
} | |||
} | |||
class ListStyle extends SkipModel { | |||
String title; | |||
class ListStyle extends SkipModel{ | |||
String img; | |||
String title; | |||
String subTitle; | |||
String typeListKey; | |||
String rightIcon; | |||
String typeListKey; | |||
String requiredLogin; | |||
String requiredTaobaoAuth; | |||
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) { | |||
super.fromJson(json); | |||
title = json['title']; | |||
img = json['img']; | |||
title = json['title']; | |||
subTitle = json['sub_title']; | |||
typeListKey = json['type_list_key']; | |||
rightIcon = json['right_icon']; | |||
typeListKey = json['type_list_key']; | |||
requiredLogin = json['required_login']; | |||
requiredTaobaoAuth = json['required_taobao_auth']; | |||
skipIdentifier = json['skip_identifier']; | |||
@@ -155,11 +170,11 @@ class ListStyle extends SkipModel { | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = super.toJson(); | |||
data['title'] = this.title; | |||
data['img'] = this.img; | |||
data['title'] = this.title; | |||
data['sub_title'] = this.subTitle; | |||
data['type_list_key'] = this.typeListKey; | |||
data['right_icon'] = this.rightIcon; | |||
data['type_list_key'] = this.typeListKey; | |||
data['required_login'] = this.requiredLogin; | |||
data['required_taobao_auth'] = this.requiredTaobaoAuth; | |||
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 'bloc.dart'; | |||
abstract class HomeNoticeEvent extends Equatable { | |||
const HomeNoticeEvent(); | |||
abstract class CustomNoticeEvent extends Equatable { | |||
const CustomNoticeEvent(); | |||
@override | |||
List<Object> get props => []; | |||
} | |||
/// 初始化事件 | |||
class HomeNoticeInitEvent extends HomeNoticeEvent{ | |||
class CustomNoticeInitEvent extends CustomNoticeEvent{ | |||
final Map<String, dynamic> model; | |||
const HomeNoticeInitEvent({this.model}); | |||
const CustomNoticeInitEvent({this.model}); | |||
@override | |||
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; | |||
const HomeNoticeSkeleton({this.map}); | |||
const CustomNoticeSkeleton({this.map}); | |||
@override | |||
Widget build(BuildContext context) { |
@@ -2,81 +2,84 @@ import 'dart:async'; | |||
import 'package:flutter/material.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:zhiying_comm/zhiying_comm.dart'; | |||
import 'package:zhiying_base_widget/widgets/home/home_notice/model/home_notice_model.dart'; | |||
import 'bloc/bloc.dart'; | |||
import 'custom_notice_sk.dart'; | |||
/// | |||
/// 公告滚动widget | |||
/// | |||
class HomeNoticeWidget extends StatelessWidget { | |||
class CustomNoticeWidget extends StatelessWidget { | |||
final Map<String, dynamic> model; | |||
const HomeNoticeWidget(this.model); | |||
const CustomNoticeWidget(this.model); | |||
@override | |||
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 | |||
_HomeNoticeWidgetContianerState createState() => _HomeNoticeWidgetContianerState(); | |||
_CustomNoticeWidgetContainerState createState() => _CustomNoticeWidgetContainerState(); | |||
} | |||
class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||
class _CustomNoticeWidgetContainerState extends State<_CustomNoticeWidgetContainer> { | |||
/// 子item点击事件 | |||
void _itemOnClick(HomeNoticeModel model) { | |||
if(pageIndex == model.notices.length){ | |||
void _itemOnClick(CustomNoticeModel model) { | |||
if (pageIndex == model.listStyle.length) { | |||
pageIndex = 0; | |||
} | |||
print('===== $pageIndex'); | |||
HomeNoticeNoticesModel item = model.notices[pageIndex]; | |||
NoticeListStyle item = model.listStyle[pageIndex]; | |||
_itemJump(item); | |||
} | |||
/// 子item跳转 | |||
void _itemJump(HomeNoticeNoticesModel model){ | |||
print('${model?.notice_text}'); | |||
void _itemJump(NoticeListStyle model) { | |||
print('${model?.contentText}'); | |||
RouterUtil.route(model, model.toJson(), context); | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
return BlocConsumer<HomeNoticeBloc, HomeNoticeState>( | |||
return BlocConsumer<CustomNoticeBloc, CustomNoticeState>( | |||
listener: (context, state) {}, | |||
buildWhen: (prev, current) { | |||
return true; | |||
}, | |||
builder: (context, state) { | |||
if (state is HomeNoticeLoadedState) { | |||
if (state is CustomNoticeLoadedState) { | |||
return _getMainWidget(state?.model); | |||
} | |||
return HomeNoticeSkeleton(); | |||
return CustomNoticeSkeleton(); | |||
}, | |||
); | |||
} | |||
/// 主体页面 | |||
Widget _getMainWidget(HomeNoticeModel model) { | |||
Widget _getMainWidget(CustomNoticeModel model) { | |||
return Container( | |||
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( | |||
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), | |||
// height: 30, | |||
width: double.infinity, | |||
child: _getChildWidget(model), | |||
), | |||
@@ -85,7 +88,7 @@ class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||
var pageIndex = 0; | |||
Widget _getChildWidget(HomeNoticeModel model) { | |||
Widget _getChildWidget(CustomNoticeModel model) { | |||
return GestureDetector( | |||
onTap: () => _itemOnClick(model), | |||
behavior: HitTestBehavior.opaque, | |||
@@ -94,7 +97,7 @@ class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||
/// 图片 | |||
// Container(width: 52, height: 13, color: Colors.red), | |||
CachedNetworkImage( | |||
imageUrl: model?.logo_img ?? '', | |||
imageUrl: model?.appNameImg ?? '', | |||
width: 52, | |||
), | |||
const SizedBox(width: 14), | |||
@@ -107,10 +110,10 @@ class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||
alignment: Alignment.centerLeft, | |||
// color: Colors.yellowAccent, | |||
child: MarqueeWidget( | |||
model?.notices?.length ?? 0, | |||
model?.listStyle?.length ?? 0, | |||
(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, | |||
), | |||
@@ -119,7 +122,7 @@ class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> { | |||
const SizedBox(width: 14), | |||
/// 图片 | |||
CachedNetworkImage(imageUrl: model?.jump_img ?? '', height: 18), | |||
CachedNetworkImage(imageUrl: model?.jumpImg ?? '', height: 18), | |||
// Container( | |||
// width: 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) { | |||
return Container( | |||
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( | |||
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)); | |||
} | |||
@@ -10,6 +10,10 @@ class CustomSearchModel { | |||
String isShow; | |||
String topMargin; | |||
String leftRightMargin; | |||
String topLeftRadius; | |||
String topRightRadius; | |||
String bottomLeftRadius; | |||
String bottomRightRadius; | |||
String bgColor; | |||
ListStyle listStyle; | |||
@@ -25,6 +29,10 @@ class CustomSearchModel { | |||
this.leftRightMargin, | |||
this.bgColor, | |||
this.listStyle, | |||
this.topLeftRadius, | |||
this.topRightRadius, | |||
this.bottomLeftRadius, | |||
this.bottomRightRadius, | |||
}); | |||
CustomSearchModel.fromJson(Map<String, dynamic> json) { | |||
@@ -38,6 +46,10 @@ class CustomSearchModel { | |||
topMargin = json['top_margin']; | |||
leftRightMargin = json['left_right_margin']; | |||
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; | |||
} | |||
@@ -53,6 +65,10 @@ class CustomSearchModel { | |||
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; | |||
if (this.listStyle != null) { | |||
data['list_style'] = this.listStyle.toJson(); | |||
} | |||
@@ -99,50 +99,87 @@ class _CustomSlideBannerContainerState extends State<CustomSlideBannerContainer> | |||
}); | |||
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( | |||
margin: EdgeInsets.all(10), | |||
width: double.infinity, | |||
height: 140, | |||
height: imgHeight + verticalPadding * 2, | |||
// 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) { | |||
// 一张图片就不滑动 | |||
if(pageCount <= 1){ | |||
if (pageCount <= 1) { | |||
return null; | |||
} | |||
@@ -134,7 +134,6 @@ class _GoodsDetailsSlideBannerContainerState | |||
if ('1' != model.pagination_open) { | |||
return null; | |||
} | |||
if ('type_number' == model.pagination) { | |||
return _getNumswiperPlugin(pageCount, model.pagination_select_color, | |||
model.pagination_unselect_color); | |||
@@ -234,7 +233,7 @@ class _GoodsDetailsSlideBannerContainerState | |||
SwiperPlugin _swiperCustomPaginationDito( | |||
int pageCount, String selectColor, String unselectColor) { | |||
return SwiperPagination( | |||
margin: const EdgeInsets.only(), | |||
margin: const EdgeInsets.only(bottom: 10), | |||
builder: DotSwiperPaginationBuilder( | |||
color: HexColor.fromHex(unselectColor), | |||
activeColor: HexColor.fromHex(selectColor), | |||
@@ -9,12 +9,12 @@ import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class HomeAuth extends StatefulWidget { | |||
final Map<String, dynamic> data; | |||
Map<String, dynamic> _json; | |||
HomeAuthModel _style; | |||
HomeAuthModel _model; | |||
HomeAuth(this.data, {Key key}) : super(key: key) { | |||
String d = data['data']; | |||
_json = convert.jsonDecode(d); | |||
_style = HomeAuthModel.fromJson(Map<String, dynamic>.from(_json)); | |||
_model = HomeAuthModel.fromJson(Map<String, dynamic>.from(_json)); | |||
} | |||
@override | |||
@@ -52,13 +52,12 @@ class _HomeAuthState extends State<HomeAuth> { | |||
width: double.infinity, | |||
margin: EdgeInsets.only(left: 12, right: 12, top: 4, bottom: 4), | |||
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), | |||
boxShadow: [ | |||
BoxShadow( | |||
offset: Offset(2, 1), //x,y轴 | |||
color: HexColor.fromHex( | |||
widget._style?.taoaboTipShadowColor ?? '767676') | |||
color: HexColor.fromHex('767676') | |||
.withAlpha(70), //投影颜色 | |||
blurRadius: 5 //投影距离 | |||
) | |||
@@ -70,19 +69,19 @@ class _HomeAuthState extends State<HomeAuth> { | |||
width: 20, | |||
height: 20, | |||
child: CachedNetworkImage( | |||
imageUrl: widget._style.taobaoAuthIcon, | |||
imageUrl: !_isAuth ? widget._model?.listStyle?.before?.auditImg ?? '' : widget?._model?.listStyle?.after?.auditImg ?? '', | |||
fit: BoxFit.contain, | |||
), | |||
), | |||
Expanded( | |||
child: Text( | |||
widget._style?.taoaboTipText ?? '', | |||
!_isAuth ? widget._model?.listStyle?.before?.contentText ?? '' : widget?._model?.listStyle?.after?.contentText ?? '', | |||
maxLines: 1, | |||
style: TextStyle( | |||
fontSize: 12, | |||
fontWeight: FontWeight.bold, | |||
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), | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex( | |||
widget._style?.taoaboTipBtnBgColor ?? 'FF4242'), | |||
!_isAuth ? widget._model?.listStyle?.before?.btnBgColor ?? 'FF4242' : widget?._model?.listStyle?.after?.btnBgColor ?? 'FF4242' ), | |||
borderRadius: BorderRadius.circular(20)), | |||
child: Text( | |||
widget._style?.taoaboTipBtnText ?? '', | |||
!_isAuth ? widget._model?.listStyle?.before?.btnText ?? '' : widget?._model?.listStyle?.after?.btnText ?? '', | |||
style: TextStyle( | |||
fontSize: 12, | |||
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 { | |||
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( | |||
{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) { | |||
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() { | |||
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; | |||
} | |||
} | |||
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 '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_comm/util/base_bloc.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class HomeGoodsBloc extends BlocBase { | |||
class HomeGoodsBloc extends BlocBase implements CategoryGoodsOnClickCallBack{ | |||
List<HomeGoodsModel> _goods = List(); | |||
String _provider = ''; | |||
String providerss = ''; | |||
int _page = 1; | |||
StreamController<List<HomeGoodsModel>> _goodsController = StreamController<List<HomeGoodsModel>>(); | |||
@@ -67,4 +68,12 @@ class HomeGoodsBloc extends BlocBase { | |||
_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:flutter/material.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'; | |||
class GoodsListCreater extends WidgetCreater { | |||
final EventBus _eventBus = EventBus(); | |||
@override | |||
List<Widget> createWidgets(Map<String, dynamic> model) { | |||
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 [ | |||
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), | |||
]; | |||
} | |||
@@ -109,6 +109,7 @@ class _HomeGoodsHeaderState extends State<_HomeGoodsHeader> | |||
width: double.infinity, | |||
height: double.infinity, | |||
color: Color(0xfff9f9f9), | |||
// color: Colors.yellow, | |||
child: TabBar( | |||
indicatorColor: Colors.transparent, | |||
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:flutter/material.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'; | |||
class MineNavBg extends StatefulWidget { | |||
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 | |||
_MineNavBgState createState() => _MineNavBgState(); | |||
@@ -20,13 +29,13 @@ class _MineNavBgState extends State<MineNavBg> { | |||
void _updateBg() { | |||
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( | |||
Container( | |||
width: double.infinity, | |||
height: statusBarHeight + 250, | |||
child: CachedNetworkImage( | |||
imageUrl: widget.data['img'], | |||
imageUrl: widget.model['img'], | |||
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/empty/empty.png | |||
- assets/images/qrcode/default_qrcode.png | |||
- assets/images/loading/loading.gif | |||
# | |||
# For details regarding assets in packages, see | |||
# https://flutter.dev/assets-and-images/#from-packages | |||