@@ -0,0 +1 @@ | |||||
{"sdk":"2.7.2 (Mon Mar 23 22:11:27 2020 +0100) on \"macos_x64\"","analyzer":"/Users/fnuser/.pub-cache/hosted/pub.flutter-io.cn/analyzer-0.39.14","build_resolvers":"/Users/fnuser/.pub-cache/hosted/pub.flutter-io.cn/build_resolvers-1.3.11"} |
@@ -680,7 +680,7 @@ | |||||
"languageVersion": "2.1" | "languageVersion": "2.1" | ||||
} | } | ||||
], | ], | ||||
"generated": "2020-09-07T03:45:53.992384Z", | |||||
"generated": "2020-09-08T07:00:40.458603Z", | |||||
"generator": "pub", | "generator": "pub", | ||||
"generatorVersion": "2.7.2" | "generatorVersion": "2.7.2" | ||||
} | } |
@@ -0,0 +1,5 @@ | |||||
<component name="ProjectCodeStyleConfiguration"> | |||||
<state> | |||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" /> | |||||
</state> | |||||
</component> |
@@ -0,0 +1,13 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="SaveActionSettings"> | |||||
<option name="actions"> | |||||
<set> | |||||
<option value="activate" /> | |||||
<option value="organizeImports" /> | |||||
<option value="reformat" /> | |||||
</set> | |||||
</option> | |||||
<option name="configurationPath" value="" /> | |||||
</component> | |||||
</project> |
@@ -2,7 +2,6 @@ import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:zhiying_base_widget/pages/main_page/main_page_bloc.dart'; | import 'package:zhiying_base_widget/pages/main_page/main_page_bloc.dart'; | ||||
import 'package:zhiying_base_widget/pages/main_page/main_page_notifier.dart'; | import 'package:zhiying_base_widget/pages/main_page/main_page_notifier.dart'; | ||||
import 'package:zhiying_base_widget/pages/main_page/main_page_sk.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:provider/provider.dart'; | import 'package:provider/provider.dart'; | ||||
import 'package:zhiying_comm/util/base_bloc.dart'; | import 'package:zhiying_comm/util/base_bloc.dart'; | ||||
@@ -25,11 +24,13 @@ class _MainPageState extends State<MainPage> { | |||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Scaffold( | return Scaffold( | ||||
backgroundColor: Color(0xfff9f9f9), | backgroundColor: Color(0xfff9f9f9), | ||||
body: ChangeNotifierProvider( | |||||
create: (context) => MainPageNotifier(), | |||||
child: BlocProvider<MainPageBloc>( | |||||
bloc: MainPageBloc(), | |||||
child: _MainPageContainer(widget.data), | |||||
body: SafeArea( | |||||
child: ChangeNotifierProvider( | |||||
create: (context) => MainPageNotifier(), | |||||
child: BlocProvider<MainPageBloc>( | |||||
bloc: MainPageBloc(), | |||||
child: _MainPageContainer(widget.data), | |||||
), | |||||
), | ), | ||||
), | ), | ||||
); | ); | ||||
@@ -46,29 +47,16 @@ class _MainPageContainer extends StatefulWidget { | |||||
} | } | ||||
class _MainPageContainerState extends State<_MainPageContainer> { | class _MainPageContainerState extends State<_MainPageContainer> { | ||||
WidgetType _type = WidgetType.normal; | |||||
bool _isEnded = false; | bool _isEnded = false; | ||||
ScrollController _controller = ScrollController(); | ScrollController _controller = ScrollController(); | ||||
MainPageBloc _bloc; | MainPageBloc _bloc; | ||||
List<String> items = ["1", "2", "3", "4", "5", "6", "7", "8"]; | |||||
RefreshController _refreshController = | RefreshController _refreshController = | ||||
RefreshController(initialRefresh: false); | RefreshController(initialRefresh: false); | ||||
void _onRefresh() async { | |||||
// monitor network fetch | |||||
await Future.delayed(Duration(milliseconds: 1000)); | |||||
// if failed,use refreshFailed() | |||||
_refreshController.refreshCompleted(); | |||||
} | |||||
void _onLoading() async { | void _onLoading() async { | ||||
// monitor network fetch | |||||
await Future.delayed(Duration(milliseconds: 1000)); | |||||
// if failed,use loadFailed(),if no data return,use LoadNodata() | |||||
items.add((items.length + 1).toString()); | |||||
if (mounted) setState(() {}); | |||||
_refreshController.loadComplete(); | |||||
// await Future.delayed(Duration(milliseconds: 1000)); | |||||
// if (mounted) setState(() {}); | |||||
// _refreshController.loadComplete(); | |||||
} | } | ||||
@override | @override | ||||
@@ -80,7 +68,6 @@ class _MainPageContainerState extends State<_MainPageContainer> { | |||||
@override | @override | ||||
void initState() { | void initState() { | ||||
_bloc = BlocProvider.of<MainPageBloc>(context); | _bloc = BlocProvider.of<MainPageBloc>(context); | ||||
_reload(); | |||||
_controller.addListener(() { | _controller.addListener(() { | ||||
// print('${_controller.offset} ${_controller.position.maxScrollExtent}'); | // print('${_controller.offset} ${_controller.position.maxScrollExtent}'); | ||||
if (_controller.offset >= _controller.position.maxScrollExtent && | if (_controller.offset >= _controller.position.maxScrollExtent && | ||||
@@ -97,79 +84,16 @@ class _MainPageContainerState extends State<_MainPageContainer> { | |||||
super.initState(); | super.initState(); | ||||
} | } | ||||
void _reload() { | |||||
setState(() { | |||||
_type = WidgetType.skeleton; | |||||
}); | |||||
WidgetModel model = WidgetModel.fromJson(widget.data); | |||||
if ((model?.components?.length ?? 0) > 0) { | |||||
_bloc.loadData(model.components.map((item) => item.modId).toList()); | |||||
} | |||||
// Future.delayed(Duration(seconds: 3), () { | |||||
// setState(() { | |||||
// _type = WidgetType.normal; | |||||
// }); | |||||
// }); | |||||
} | |||||
List<Widget> _createContent(BuildContext context) { | |||||
List<Widget> list = List(); | |||||
list.add(SliverToBoxAdapter( | |||||
child: RaisedButton( | |||||
onPressed: () { | |||||
Provider.of<MainPageNotifier>(context, listen: false).loadMore(); | |||||
_reload(); | |||||
}, | |||||
child: Text('重置'), | |||||
), | |||||
)); | |||||
list.addAll(WidgetFactory.create('index_carousel', | |||||
type: _type, | |||||
isSliver: true, | |||||
model: Map<String, dynamic>.from({'aaaaa': 'bbbb'}))); | |||||
list.addAll(WidgetFactory.create('home_quick_entry', type: _type, isSliver: true)); | |||||
list.addAll(WidgetFactory.create('index_recommend_list', | |||||
type: _type, isSliver: true)); | |||||
return list; | |||||
} | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return StreamBuilder<List<List<Map<String, dynamic>>>>( | |||||
return StreamBuilder<Map<String, dynamic>>( | |||||
stream: _bloc.outData, | stream: _bloc.outData, | ||||
builder: (BuildContext context, AsyncSnapshot snapshot) { | builder: (BuildContext context, AsyncSnapshot snapshot) { | ||||
if (snapshot.data == null) { | |||||
return MainPageSkeleton(); | |||||
} | |||||
_type = WidgetType.normal; | |||||
return SmartRefresher( | return SmartRefresher( | ||||
enablePullDown: true, | enablePullDown: true, | ||||
enablePullUp: true, | |||||
enablePullUp: false, | |||||
header: WaterDropHeader(), | header: WaterDropHeader(), | ||||
footer: CustomFooter( | |||||
builder: (BuildContext context, LoadStatus mode) { | |||||
Widget body; | |||||
if (mode == LoadStatus.idle) { | |||||
body = Text("上拉加载"); | |||||
} else if (mode == LoadStatus.loading) { | |||||
body = CupertinoActivityIndicator(); | |||||
} else if (mode == LoadStatus.failed) { | |||||
body = Text("加载失败!点击重试!"); | |||||
} else if (mode == LoadStatus.canLoading) { | |||||
body = Text("松手,加载更多!"); | |||||
} else { | |||||
body = Text("没有更多数据了!"); | |||||
} | |||||
return Container( | |||||
height: 55.0, | |||||
child: Center(child: body), | |||||
); | |||||
}, | |||||
), | |||||
controller: _refreshController, | controller: _refreshController, | ||||
onRefresh: _onRefresh, | |||||
onLoading: _onLoading, | onLoading: _onLoading, | ||||
child: CustomScrollView( | child: CustomScrollView( | ||||
controller: _controller, | controller: _controller, | ||||
@@ -179,4 +103,26 @@ class _MainPageContainerState extends State<_MainPageContainer> { | |||||
}, | }, | ||||
); | ); | ||||
} | } | ||||
List<Widget> _createContent(BuildContext context) { | |||||
WidgetModel model = WidgetModel.fromJson(widget.data); | |||||
List<Widget> list = List(); | |||||
for (int i = 0; i < model.components.length; i++) { | |||||
WidgetModel item = model.components[i]; | |||||
Map<String, dynamic> data = null; | |||||
if (widget.data.containsKey('components')) { | |||||
data = widget.data['components'][i]; | |||||
} | |||||
list.addAll(WidgetFactory.create( | |||||
item.modName, | |||||
type: WidgetType.skeleton, | |||||
isSliver: true, | |||||
model: data, | |||||
)); | |||||
} | |||||
model.components.forEach((item) {}); | |||||
return list; | |||||
} | |||||
} | } |
@@ -4,12 +4,11 @@ import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | import 'package:zhiying_comm/util/base_bloc.dart'; | ||||
class MainPageBloc extends BlocBase { | class MainPageBloc extends BlocBase { | ||||
List<List<Map<String, dynamic>>> _mains = List(); | |||||
Map<String, dynamic> _mains = Map(); | |||||
StreamController<List<List<Map<String, dynamic>>>> _mainController = | |||||
StreamController<List<List<Map<String, dynamic>>>>(); | |||||
Stream<List<List<Map<String, dynamic>>>> get outData => | |||||
_mainController.stream; | |||||
StreamController<Map<String, dynamic>> _mainController = | |||||
StreamController<Map<String, dynamic>>(); | |||||
Stream<Map<String, dynamic>> get outData => _mainController.stream; | |||||
@override | @override | ||||
void dispose() { | void dispose() { | ||||
@@ -18,20 +17,12 @@ class MainPageBloc extends BlocBase { | |||||
} | } | ||||
void loadData(List<int> ids) { | void loadData(List<int> ids) { | ||||
NetUtil.request('/api/v1/mod', | |||||
method: NetMethod.POST, | |||||
params: Map<String, dynamic>.from({'ids': ids}), onSuccess: (data) { | |||||
Map<String, dynamic> datas = data; | |||||
List<List<Map<String, dynamic>>> result = List(); | |||||
for (int id in ids) { | |||||
if (datas.containsKey(id.toString())) { | |||||
result.add(List<Map<String, dynamic>>.from(datas[id.toString()])); | |||||
} else { | |||||
result.add(List<Map<String, dynamic>>()); | |||||
} | |||||
} | |||||
_mains = result; | |||||
_mainController.add(_mains); | |||||
NetUtil.request('/api/v1/config.json', onSuccess: (data) { | |||||
List list = data; | |||||
List<Map<String, dynamic>> tabs = list.map((item) { | |||||
return Map<String, dynamic>.from(item); | |||||
}).toList(); | |||||
_mainController.add(tabs.first); | |||||
}); | }); | ||||
} | } | ||||
} | } |
@@ -1,33 +0,0 @@ | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
// ignore: must_be_immutable | |||||
class MainPageSkeleton extends StatelessWidget { | |||||
ScrollController _controller; | |||||
MainPageSkeleton({Key key}) : super(key: key) { | |||||
_controller = ScrollController(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return SafeArea( | |||||
child: CustomScrollView( | |||||
controller: _controller, | |||||
slivers: _createContent(context), | |||||
), | |||||
); | |||||
} | |||||
List<Widget> _createContent(BuildContext context) { | |||||
List<Widget> list = List(); | |||||
list.addAll(WidgetFactory.create('index_carousel', | |||||
type: WidgetType.skeleton, | |||||
isSliver: true, | |||||
model: Map<String, dynamic>.from({'aaaaa': 'bbbb'}))); | |||||
list.addAll(WidgetFactory.create('index_recommend_list', | |||||
type: WidgetType.skeleton, isSliver: true)); | |||||
return list; | |||||
} | |||||
} |
@@ -0,0 +1,64 @@ | |||||
import 'dart:async'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/models/home_goods_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/models/home_goods_style_model.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class HomeGoodsBloc extends BlocBase { | |||||
List<HomeGoodsModel> _goods = List(); | |||||
String storeName = ''; | |||||
HomeGoodsStyleModel style; | |||||
String _provider = ''; | |||||
int _page = 1; | |||||
StreamController<List<HomeGoodsModel>> _goodsController = | |||||
StreamController<List<HomeGoodsModel>>(); | |||||
Stream<List<HomeGoodsModel>> get outData => _goodsController.stream; | |||||
@override | |||||
void dispose() { | |||||
_goodsController.close(); | |||||
_goodsController = null; | |||||
} | |||||
void loadMore(String provider) { | |||||
if (provider != _provider) { | |||||
_page = 1; | |||||
} | |||||
_provider = provider; | |||||
if (_page == 1) { | |||||
_goods.clear(); | |||||
} | |||||
NetUtil.request( | |||||
'/api/v1/rec/${provider.toString()}?page=${_page.toString()}', | |||||
method: NetMethod.GET, | |||||
onCache: (data) {}, onSuccess: (data) { | |||||
Map<String, dynamic> json = Map<String, dynamic>.from(data); | |||||
if (json.containsKey('good')) { | |||||
List<dynamic> list = json['good']; | |||||
List<HomeGoodsModel> goods = list.map((item) { | |||||
return HomeGoodsModel.fromJson(Map<String, dynamic>.from(item)); | |||||
}).toList(); | |||||
if (goods.length > 0) { | |||||
_page++; | |||||
} | |||||
_goods.addAll(goods); | |||||
} | |||||
if (json.containsKey('style')) { | |||||
style = HomeGoodsStyleModel.fromJson( | |||||
Map<String, dynamic>.from(json['style'])); | |||||
} | |||||
if (json.containsKey('provider_name')) { | |||||
storeName = json['provider_name'].toString(); | |||||
} | |||||
_goodsController.add(_goods); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,40 @@ | |||||
import 'dart:async'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/models/home_goods_header_model.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
class HomeGoodsHeaderBloc extends BlocBase { | |||||
List<HomeGoodsHeaderModel> _tabs = List(); | |||||
StreamController<List<HomeGoodsHeaderModel>> _tabController = | |||||
StreamController<List<HomeGoodsHeaderModel>>(); | |||||
Stream<List<HomeGoodsHeaderModel>> get outData => _tabController.stream; | |||||
@override | |||||
void dispose() { | |||||
_tabController.close(); | |||||
_tabController = null; | |||||
} | |||||
void loadData(int id) { | |||||
NetUtil.request('/api/v1/mod', | |||||
method: NetMethod.POST, | |||||
params: Map<String, dynamic>.from({ | |||||
'ids': [id] | |||||
}), | |||||
onCache: (data) {}, onSuccess: (data) { | |||||
String key = id.toString(); | |||||
Map<String, dynamic> json = Map<String, dynamic>.from(data); | |||||
if (json.containsKey(key)) { | |||||
List<dynamic> list = json[key]; | |||||
_tabs = list.map((item) { | |||||
return HomeGoodsHeaderModel.fromJson(Map<String, dynamic>.from(item)); | |||||
}).toList(); | |||||
} | |||||
_tabController.add(_tabs); | |||||
}); | |||||
} | |||||
} |
@@ -1,10 +1,20 @@ | |||||
import 'package:event_bus/event_bus.dart'; | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:provider/provider.dart'; | import 'package:provider/provider.dart'; | ||||
import 'package:zhiying_base_widget/pages/main_page/main_page_notifier.dart'; | import 'package:zhiying_base_widget/pages/main_page/main_page_notifier.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home_goods/bloc/home_goods_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/home_goods_creater.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/home_goods_item.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/models/home_goods_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/skeleton/home_goods_sk.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
class HomeGoods extends StatefulWidget { | class HomeGoods extends StatefulWidget { | ||||
HomeGoods({Key key}) : super(key: key); | |||||
final Map<String, dynamic> data; | |||||
final EventBus eventBus; | |||||
HomeGoods(this.data, {Key key, this.eventBus}) : super(key: key); | |||||
@override | @override | ||||
_HomeGoodsState createState() => _HomeGoodsState(); | _HomeGoodsState createState() => _HomeGoodsState(); | ||||
@@ -16,13 +26,48 @@ class _HomeGoodsState extends State<HomeGoods> { | |||||
super.initState(); | super.initState(); | ||||
} | } | ||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocProvider<HomeGoodsBloc>( | |||||
bloc: HomeGoodsBloc(), | |||||
child: _HomeGoodsContainer(widget.data, widget.eventBus), | |||||
); | |||||
} | |||||
} | |||||
class _HomeGoodsContainer extends StatefulWidget { | |||||
final Map<String, dynamic> data; | |||||
final EventBus eventBus; | |||||
_HomeGoodsContainer(this.data, this.eventBus, {Key key}) : super(key: key); | |||||
@override | |||||
_HomeGoodsContainerState createState() => _HomeGoodsContainerState(); | |||||
} | |||||
class _HomeGoodsContainerState extends State<_HomeGoodsContainer> { | |||||
HomeGoodsBloc _bloc; | |||||
String _provider = ''; | |||||
@override | |||||
void initState() { | |||||
_bloc = BlocProvider.of<HomeGoodsBloc>(context); | |||||
widget.eventBus.on<HomeGoodsHeaderEvent>().listen((data) { | |||||
_provider = data.provider; | |||||
_bloc.loadMore(_provider); | |||||
}); | |||||
super.initState(); | |||||
} | |||||
@override | @override | ||||
void didChangeDependencies() { | void didChangeDependencies() { | ||||
super.didChangeDependencies(); | super.didChangeDependencies(); | ||||
print('didChangeDependencies'); | print('didChangeDependencies'); | ||||
bool isNeedLoadMore = Provider.of<MainPageNotifier>(context).scrollEnd; | bool isNeedLoadMore = Provider.of<MainPageNotifier>(context).scrollEnd; | ||||
if (isNeedLoadMore) { | |||||
if (isNeedLoadMore && _provider != '') { | |||||
print('HomeGoods loadmore...'); | print('HomeGoods loadmore...'); | ||||
_bloc.loadMore(_provider); | |||||
} | } | ||||
} | } | ||||
@@ -30,19 +75,28 @@ class _HomeGoodsState extends State<HomeGoods> { | |||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Container( | return Container( | ||||
width: double.infinity, | width: double.infinity, | ||||
child: ListView.builder( | |||||
shrinkWrap: true, | |||||
physics: NeverScrollableScrollPhysics(), | |||||
itemCount: 20, | |||||
itemBuilder: (context, index) { | |||||
return Container( | |||||
width: double.infinity, | |||||
height: 70, | |||||
color: Colors.primaries[index % Colors.primaries.length], | |||||
child: Text( | |||||
Provider.of<MainPageNotifier>(context).scrollEnd.toString()), | |||||
); | |||||
}), | |||||
child: StreamBuilder<List<HomeGoodsModel>>( | |||||
stream: _bloc.outData, | |||||
builder: (BuildContext context, AsyncSnapshot snapshot) { | |||||
if (snapshot.data == null) { | |||||
return HomeGoodsSkeleton(); | |||||
} | |||||
List<HomeGoodsModel> goods = snapshot.data; | |||||
return ListView.builder( | |||||
shrinkWrap: true, | |||||
physics: NeverScrollableScrollPhysics(), | |||||
itemCount: goods.length, | |||||
itemBuilder: (context, index) { | |||||
return HomeGoodsItem( | |||||
goods[index], | |||||
_bloc.style, | |||||
data: widget.data, | |||||
shop: _bloc.storeName, | |||||
); | |||||
}); | |||||
}, | |||||
), | |||||
); | ); | ||||
} | } | ||||
} | } |
@@ -1,45 +1,42 @@ | |||||
import 'package:event_bus/event_bus.dart'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home_goods/bloc/home_goods_header_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/home_goods.dart'; | import 'package:zhiying_base_widget/widgets/home_goods/home_goods.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home_goods/home_goods_header.dart'; | import 'package:zhiying_base_widget/widgets/home_goods/home_goods_header.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home_goods/skeleton/home_goods_header_sk.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/skeleton/home_goods_sk.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:event_bus/event_bus.dart'; | |||||
class GoodsListCreater extends WidgetCreater { | class GoodsListCreater extends WidgetCreater { | ||||
final EventBus _eventBus = EventBus(); | |||||
@override | @override | ||||
List<Widget> createWidgets(Map<String, dynamic> model) { | List<Widget> createWidgets(Map<String, dynamic> model) { | ||||
EventBus eventBus = EventBus(); | |||||
return [ | |||||
SliverPersistentHeader( | |||||
pinned: true, | |||||
floating: false, | |||||
delegate: HomeGoodsDelegate(), | |||||
), | |||||
SliverToBoxAdapter( | |||||
child: HomeGoods(), | |||||
), | |||||
]; | |||||
} | |||||
print('创建商品列表'); | |||||
Widget _widget = BlocProvider<HomeGoodsHeaderBloc>( | |||||
bloc: HomeGoodsHeaderBloc(), | |||||
child: HomeGoodsHeader(model, _eventBus), | |||||
); | |||||
@override | |||||
List<Widget> createSkeleton(Map<String, dynamic> model) { | |||||
return [ | return [ | ||||
SliverPersistentHeader( | SliverPersistentHeader( | ||||
pinned: true, | |||||
floating: false, | |||||
delegate: HomeGoodsHeaderSkeletonDelegate(), | |||||
), | |||||
pinned: true, | |||||
floating: false, | |||||
delegate: HomeGoodsHeaderDelegate(_widget), | |||||
), | |||||
SliverToBoxAdapter( | SliverToBoxAdapter( | ||||
child: HomeGoodsSkeleton(), | |||||
), | |||||
child: HomeGoods(model, eventBus: _eventBus), | |||||
), | |||||
]; | ]; | ||||
} | } | ||||
@override | @override | ||||
bool isSliverChild() { | bool isSliverChild() { | ||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
class HomeGoodsHeaderEvent { | |||||
String provider; | |||||
HomeGoodsHeaderEvent(this.provider); | |||||
} |
@@ -1,27 +1,22 @@ | |||||
import 'package:event_bus/event_bus.dart'; | |||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home_goods/bloc/home_goods_header_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/home_goods_creater.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/models/home_goods_header_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/skeleton/home_goods_header_sk.dart'; | |||||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
class HomeGoodsDelegate extends SliverPersistentHeaderDelegate { | |||||
class HomeGoodsHeaderDelegate extends SliverPersistentHeaderDelegate { | |||||
final Widget child; | |||||
HomeGoodsHeaderDelegate(this.child) : super(); | |||||
@override | @override | ||||
Widget build( | Widget build( | ||||
BuildContext context, double shrinkOffset, bool overlapsContent) { | BuildContext context, double shrinkOffset, bool overlapsContent) { | ||||
// print(shrinkOffset.toString()); | |||||
return Container( | |||||
color: Colors.red, | |||||
alignment: Alignment.center, | |||||
child: TabBar( | |||||
controller: TabController(initialIndex: 0, length: 6, vsync: ScrollableState()), | |||||
isScrollable: true, | |||||
tabs: <Widget>[ | |||||
Tab(icon: Icon(Icons.local_florist)), | |||||
Tab(icon: Icon(Icons.change_history)), | |||||
Tab(icon: Icon(Icons.directions_bike)), | |||||
Tab(icon: Icon(Icons.local_florist)), | |||||
Tab(icon: Icon(Icons.change_history)), | |||||
Tab(icon: Icon(Icons.directions_bike)), | |||||
], | |||||
), | |||||
); | |||||
return child; | |||||
} | } | ||||
@override | @override | ||||
@@ -34,3 +29,167 @@ class HomeGoodsDelegate extends SliverPersistentHeaderDelegate { | |||||
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => | bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => | ||||
false; // 如果内容需要更新,设置为true | false; // 如果内容需要更新,设置为true | ||||
} | } | ||||
class HomeGoodsHeader extends StatelessWidget { | |||||
final Map<String, dynamic> model; | |||||
final EventBus eventBus; | |||||
const HomeGoodsHeader( | |||||
this.model, | |||||
this.eventBus, { | |||||
Key key, | |||||
}) : super(key: key); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocProvider<HomeGoodsHeaderBloc>( | |||||
bloc: HomeGoodsHeaderBloc(), | |||||
child: _HomeGoodsHeader(model, eventBus), | |||||
); | |||||
} | |||||
} | |||||
class _HomeGoodsHeader extends StatefulWidget { | |||||
final Map<String, dynamic> model; | |||||
final EventBus eventBus; | |||||
_HomeGoodsHeader(this.model, this.eventBus, {Key key}) : super(key: key); | |||||
@override | |||||
_HomeGoodsHeaderState createState() => _HomeGoodsHeaderState(); | |||||
} | |||||
class _HomeGoodsHeaderState extends State<_HomeGoodsHeader> { | |||||
HomeGoodsHeaderBloc _bloc; | |||||
@override | |||||
void dispose() { | |||||
_bloc.dispose(); | |||||
super.dispose(); | |||||
} | |||||
@override | |||||
void initState() { | |||||
_bloc = BlocProvider.of<HomeGoodsHeaderBloc>(context); | |||||
_bloc.loadData(widget.model['mod_id']); | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return StreamBuilder<List<HomeGoodsHeaderModel>>( | |||||
stream: _bloc.outData, | |||||
builder: (BuildContext context, AsyncSnapshot snapshot) { | |||||
if (snapshot.data == null) { | |||||
return HomeGoodsHeaderSkeleton(); | |||||
} | |||||
return HomeGoodsHeaderContainer(snapshot.data, widget.eventBus); | |||||
}); | |||||
} | |||||
} | |||||
class HomeGoodsHeaderContainer extends StatefulWidget { | |||||
final List<HomeGoodsHeaderModel> headers; | |||||
final EventBus eventBus; | |||||
HomeGoodsHeaderContainer(this.headers, this.eventBus, {Key key}) | |||||
: super(key: key); | |||||
@override | |||||
_HomeGoodsHeaderContainerState createState() => | |||||
_HomeGoodsHeaderContainerState(); | |||||
} | |||||
class _HomeGoodsHeaderContainerState extends State<HomeGoodsHeaderContainer> | |||||
with TickerProviderStateMixin { | |||||
List<Widget> _widgets = List(); | |||||
TabController _tabController; | |||||
int _currentIndex = 0; | |||||
@override | |||||
void initState() { | |||||
_tabController = TabController(length: widget.headers.length, vsync: this); | |||||
if (widget.headers.first != null) { | |||||
widget.eventBus.fire(HomeGoodsHeaderEvent(widget.headers.first.modName)); | |||||
} | |||||
super.initState(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
_widgets.clear(); | |||||
for (int index = 0; index < widget.headers.length; index++) { | |||||
_widgets.add(_HomeGoodsHeaderItem( | |||||
widget.headers[index], | |||||
isSelected: index == _currentIndex, | |||||
)); | |||||
} | |||||
return Container( | |||||
width: double.infinity, | |||||
height: double.infinity, | |||||
color: Color(0xfff9f9f9), | |||||
child: TabBar( | |||||
indicatorColor: Colors.transparent, | |||||
controller: _tabController, | |||||
isScrollable: true, | |||||
tabs: _widgets, | |||||
onTap: (index) { | |||||
widget.eventBus | |||||
.fire(HomeGoodsHeaderEvent(widget.headers[index].modName)); | |||||
setState(() { | |||||
_currentIndex = index; | |||||
}); | |||||
}, | |||||
), | |||||
); | |||||
} | |||||
} | |||||
class _HomeGoodsHeaderItem extends StatelessWidget { | |||||
final bool isSelected; | |||||
final HomeGoodsHeaderModel model; | |||||
const _HomeGoodsHeaderItem(this.model, {Key key, this.isSelected = false}) | |||||
: 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: HexColor.fromHex(model.fontColor), | |||||
fontSize: 17, | |||||
fontWeight: FontWeight.bold), | |||||
), | |||||
Container( | |||||
margin: EdgeInsets.only(top: 4), | |||||
padding: EdgeInsets.only(left: 6, right: 6, top: 2, bottom: 2), | |||||
decoration: BoxDecoration( | |||||
color: isSelected | |||||
? HexColor.fromHex(model.fontColor) | |||||
: Colors.transparent, | |||||
borderRadius: BorderRadius.circular(18)), | |||||
child: Text( | |||||
model.subtitle, | |||||
style: TextStyle( | |||||
fontSize: 10, | |||||
color: isSelected ? Colors.white : Color(0xff999999)), | |||||
textAlign: TextAlign.center, | |||||
), | |||||
), | |||||
], | |||||
), | |||||
)); | |||||
} | |||||
} |
@@ -1,15 +1,254 @@ | |||||
import 'dart:convert'; | |||||
import 'package:cached_network_image/cached_network_image.dart'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home_goods/models/home_goods_model.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home_goods/models/home_goods_style_model.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
// ignore: must_be_immutable | |||||
class HomeGoodsItem extends StatelessWidget { | class HomeGoodsItem extends StatelessWidget { | ||||
const HomeGoodsItem({Key key}) : super(key: key); | |||||
final HomeGoodsModel goods; | |||||
final HomeGoodsStyleModel style; | |||||
final String shop; | |||||
Map<String, dynamic> data; | |||||
HomeGoodsItem(this.goods, this.style, {Key key, this.data, this.shop}) | |||||
: super(key: key) { | |||||
if (this.data != null && this.data.containsKey('data')) { | |||||
String data = this.data['data']; | |||||
Map<String, dynamic> json = Map<String, dynamic>.from(jsonDecode(data)); | |||||
this.data = json; | |||||
} | |||||
} | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Container( | return Container( | ||||
margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 4, bottom: 4), | margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 4, bottom: 4), | ||||
padding: EdgeInsets.all(7.5), | |||||
decoration: BoxDecoration( | decoration: BoxDecoration( | ||||
color: Colors.white, | color: Colors.white, | ||||
borderRadius: BorderRadius.all(Radius.circular(7.5))), | borderRadius: BorderRadius.all(Radius.circular(7.5))), | ||||
child: Row( | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
Container( | |||||
width: 126, | |||||
height: 126, | |||||
margin: EdgeInsets.only(right: 10), | |||||
child: ClipRRect( | |||||
borderRadius: BorderRadius.circular(7.5), | |||||
child: CachedNetworkImage( | |||||
imageUrl: goods.goodImage, | |||||
fit: BoxFit.fitHeight, | |||||
), | |||||
), | |||||
), | |||||
Expanded( | |||||
child: Container( | |||||
height: 126, | |||||
width: double.infinity, | |||||
child: Column( | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
Container( | |||||
width: double.infinity, | |||||
child: _createTitle(), | |||||
), | |||||
_createShop(), | |||||
_createCupone(), | |||||
Expanded(child: Container()), | |||||
_createBottom(), | |||||
], | |||||
), | |||||
), | |||||
) | |||||
], | |||||
), | |||||
); | |||||
} | |||||
Widget _createTitle() { | |||||
return RichText( | |||||
maxLines: 2, | |||||
overflow: TextOverflow.ellipsis, | |||||
text: TextSpan(children: [ | |||||
WidgetSpan( | |||||
child: shop == null || shop == '' | |||||
? Container() | |||||
: Container( | |||||
padding: | |||||
EdgeInsets.only(left: 2, right: 2, top: 3, bottom: 3), | |||||
margin: EdgeInsets.only(right: 4), | |||||
child: Text( | |||||
shop, | |||||
style: TextStyle( | |||||
fontSize: 9, | |||||
height: 1, | |||||
color: HexColor.fromHex('#ffffff'), | |||||
), | |||||
), | |||||
decoration: BoxDecoration( | |||||
color: Colors.red, | |||||
borderRadius: BorderRadius.circular(2.5)), | |||||
), | |||||
), | |||||
TextSpan( | |||||
text: goods.goodTitle, | |||||
style: TextStyle( | |||||
fontSize: 15, | |||||
color: HexColor.fromHex('#333333'), | |||||
fontWeight: FontWeight.bold), | |||||
) | |||||
]), | |||||
); | |||||
} | |||||
Widget _createShop() { | |||||
return Container( | |||||
margin: EdgeInsets.only(top: 5), | |||||
width: double.infinity, | |||||
child: Row( | |||||
children: <Widget>[ | |||||
Container( | |||||
width: 15, | |||||
height: 15, | |||||
margin: EdgeInsets.only(right: 2), | |||||
child: CachedNetworkImage( | |||||
imageUrl: style.shopIcon, | |||||
fit: BoxFit.fitHeight, | |||||
), | |||||
), | |||||
Expanded( | |||||
child: Text( | |||||
goods.shopName, | |||||
style: TextStyle( | |||||
color: HexColor.fromHex(style.shopNameColor), | |||||
fontSize: 11, | |||||
fontWeight: FontWeight.w400), | |||||
)) | |||||
], | |||||
), | |||||
); | |||||
} | |||||
Widget _createCupone() { | |||||
List<Widget> widgets = List(); | |||||
if (goods.coupon != null && goods.coupon != '') { | |||||
widgets.add(Container( | |||||
margin: EdgeInsets.only(right: 5), | |||||
padding: EdgeInsets.only(left: 10, right: 10, top: 2, bottom: 2), | |||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex(style.couponBackgroundColor), | |||||
borderRadius: BorderRadius.circular(2.5), | |||||
), | |||||
child: Text( | |||||
goods.coupon, | |||||
textAlign: TextAlign.center, | |||||
maxLines: 1, | |||||
style: TextStyle( | |||||
height: 1, | |||||
fontSize: 11, | |||||
color: HexColor.fromHex(style.couponFontColor), | |||||
), | |||||
), | |||||
)); | |||||
} | |||||
if (goods.commission != null || goods.commission != '') { | |||||
widgets.add(Container( | |||||
margin: EdgeInsets.only(right: 5), | |||||
padding: EdgeInsets.only(left: 10, right: 10, top: 2, bottom: 2), | |||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex(style.commissionBackgroundColor), | |||||
borderRadius: BorderRadius.circular(2.5), | |||||
), | |||||
child: Text( | |||||
goods.commission, | |||||
textAlign: TextAlign.center, | |||||
maxLines: 1, | |||||
style: TextStyle( | |||||
height: 1, | |||||
fontSize: 11, | |||||
color: HexColor.fromHex(style.commissionFontColor), | |||||
), | |||||
), | |||||
)); | |||||
} | |||||
return Container( | |||||
margin: EdgeInsets.only(top: 6), | |||||
child: Row( | |||||
children: widgets, | |||||
), | |||||
); | |||||
} | |||||
Widget _createBottom() { | |||||
return Container( | |||||
child: Row( | |||||
crossAxisAlignment: CrossAxisAlignment.end, | |||||
children: <Widget>[ | |||||
_createPrice(), | |||||
_createOriginPrice(), | |||||
Expanded(child: Container()), | |||||
_createSale(), | |||||
], | |||||
), | |||||
); | |||||
} | |||||
Widget _createPrice() { | |||||
return RichText( | |||||
maxLines: 1, | |||||
overflow: TextOverflow.ellipsis, | |||||
text: TextSpan(children: [ | |||||
TextSpan( | |||||
text: '¥', | |||||
style: TextStyle( | |||||
fontSize: 10, | |||||
color: HexColor.fromHex(style.currentPriceColor), | |||||
fontWeight: FontWeight.bold, | |||||
fontFamily: 'Din', | |||||
package: 'zhiying_base_widget', | |||||
), | |||||
), | |||||
TextSpan( | |||||
text: goods.currentPrice, | |||||
style: TextStyle( | |||||
fontSize: 20, | |||||
color: HexColor.fromHex(style.currentPriceColor), | |||||
fontWeight: FontWeight.bold, | |||||
fontFamily: 'Din', | |||||
package: 'zhiying_base_widget', | |||||
), | |||||
) | |||||
]), | |||||
); | |||||
} | |||||
Widget _createOriginPrice() { | |||||
return Padding( | |||||
padding: EdgeInsets.only(bottom: 2), | |||||
child: Text( | |||||
'¥${goods.marketPrice}', | |||||
style: TextStyle( | |||||
fontSize: 11, | |||||
height: 1, | |||||
color: HexColor.fromHex(style.marketPriceColor), | |||||
fontWeight: FontWeight.normal, | |||||
fontFamily: 'Din', | |||||
package: 'zhiying_base_widget', | |||||
decoration: TextDecoration.lineThrough, | |||||
), | |||||
)); | |||||
} | |||||
Widget _createSale() { | |||||
return Text( | |||||
'${goods.inorderCount}', | |||||
style: TextStyle(fontSize: 11, color: HexColor.fromHex('#999999')), | |||||
); | ); | ||||
} | } | ||||
} | } |
@@ -0,0 +1,94 @@ | |||||
import 'package:json_annotation/json_annotation.dart'; | |||||
part 'home_goods_header_model.g.dart'; | |||||
@JsonSerializable() | |||||
class HomeGoodsHeaderModel extends Object { | |||||
@JsonKey(name: 'mod_id') | |||||
int modId; | |||||
@JsonKey(name: 'mod_pid') | |||||
int modPid; | |||||
@JsonKey(name: 'mod_name') | |||||
String modName; | |||||
@JsonKey(name: 'position') | |||||
String position; | |||||
@JsonKey(name: 'title') | |||||
String title; | |||||
@JsonKey(name: 'subtitle') | |||||
String subtitle; | |||||
@JsonKey(name: 'url') | |||||
String url; | |||||
@JsonKey(name: 'margin') | |||||
String margin; | |||||
@JsonKey(name: 'aspect_ratio') | |||||
String aspectRatio; | |||||
@JsonKey(name: 'icon') | |||||
String icon; | |||||
@JsonKey(name: 'img') | |||||
String img; | |||||
@JsonKey(name: 'font_color') | |||||
String fontColor; | |||||
@JsonKey(name: 'bg_img') | |||||
String bgImg; | |||||
@JsonKey(name: 'bg_color') | |||||
String bgColor; | |||||
@JsonKey(name: 'bg_color_t') | |||||
String bgColorT; | |||||
@JsonKey(name: 'badge') | |||||
String badge; | |||||
@JsonKey(name: 'path') | |||||
String path; | |||||
@JsonKey(name: 'data') | |||||
String data; | |||||
@JsonKey(name: 'sort') | |||||
int sort; | |||||
@JsonKey(name: 'is_global') | |||||
int isGlobal; | |||||
HomeGoodsHeaderModel( | |||||
this.modId, | |||||
this.modPid, | |||||
this.modName, | |||||
this.position, | |||||
this.title, | |||||
this.subtitle, | |||||
this.url, | |||||
this.margin, | |||||
this.aspectRatio, | |||||
this.icon, | |||||
this.img, | |||||
this.fontColor, | |||||
this.bgImg, | |||||
this.bgColor, | |||||
this.bgColorT, | |||||
this.badge, | |||||
this.path, | |||||
this.data, | |||||
this.sort, | |||||
this.isGlobal, | |||||
); | |||||
factory HomeGoodsHeaderModel.fromJson(Map<String, dynamic> srcJson) => | |||||
_$HomeGoodsHeaderModelFromJson(srcJson); | |||||
Map<String, dynamic> toJson() => _$HomeGoodsHeaderModelToJson(this); | |||||
} |
@@ -0,0 +1,57 @@ | |||||
// GENERATED CODE - DO NOT MODIFY BY HAND | |||||
part of 'home_goods_header_model.dart'; | |||||
// ************************************************************************** | |||||
// JsonSerializableGenerator | |||||
// ************************************************************************** | |||||
HomeGoodsHeaderModel _$HomeGoodsHeaderModelFromJson(Map<String, dynamic> json) { | |||||
return HomeGoodsHeaderModel( | |||||
json['mod_id'] as int, | |||||
json['mod_pid'] as int, | |||||
json['mod_name'] as String, | |||||
json['position'] as String, | |||||
json['title'] as String, | |||||
json['subtitle'] as String, | |||||
json['url'] as String, | |||||
json['margin'] as String, | |||||
json['aspect_ratio'] as String, | |||||
json['icon'] as String, | |||||
json['img'] as String, | |||||
json['font_color'] as String, | |||||
json['bg_img'] as String, | |||||
json['bg_color'] as String, | |||||
json['bg_color_t'] as String, | |||||
json['badge'] as String, | |||||
json['path'] as String, | |||||
json['data'] as String, | |||||
json['sort'] as int, | |||||
json['is_global'] as int, | |||||
); | |||||
} | |||||
Map<String, dynamic> _$HomeGoodsHeaderModelToJson( | |||||
HomeGoodsHeaderModel instance) => | |||||
<String, dynamic>{ | |||||
'mod_id': instance.modId, | |||||
'mod_pid': instance.modPid, | |||||
'mod_name': instance.modName, | |||||
'position': instance.position, | |||||
'title': instance.title, | |||||
'subtitle': instance.subtitle, | |||||
'url': instance.url, | |||||
'margin': instance.margin, | |||||
'aspect_ratio': instance.aspectRatio, | |||||
'icon': instance.icon, | |||||
'img': instance.img, | |||||
'font_color': instance.fontColor, | |||||
'bg_img': instance.bgImg, | |||||
'bg_color': instance.bgColor, | |||||
'bg_color_t': instance.bgColorT, | |||||
'badge': instance.badge, | |||||
'path': instance.path, | |||||
'data': instance.data, | |||||
'sort': instance.sort, | |||||
'is_global': instance.isGlobal, | |||||
}; |
@@ -0,0 +1,54 @@ | |||||
import 'package:json_annotation/json_annotation.dart'; | |||||
part 'home_goods_model.g.dart'; | |||||
@JsonSerializable() | |||||
class HomeGoodsModel extends Object { | |||||
@JsonKey(name: 'provider_name') | |||||
String providerName; | |||||
@JsonKey(name: 'good_id') | |||||
String goodId; | |||||
@JsonKey(name: 'good_image') | |||||
String goodImage; | |||||
@JsonKey(name: 'good_title') | |||||
String goodTitle; | |||||
@JsonKey(name: 'shop_name') | |||||
String shopName; | |||||
@JsonKey(name: 'coupon') | |||||
String coupon; | |||||
@JsonKey(name: 'commission') | |||||
String commission; | |||||
@JsonKey(name: 'market_price') | |||||
String marketPrice; | |||||
@JsonKey(name: 'current_price') | |||||
String currentPrice; | |||||
@JsonKey(name: 'inorder_count') | |||||
String inorderCount; | |||||
HomeGoodsModel( | |||||
this.providerName, | |||||
this.goodId, | |||||
this.goodImage, | |||||
this.goodTitle, | |||||
this.shopName, | |||||
this.coupon, | |||||
this.commission, | |||||
this.marketPrice, | |||||
this.currentPrice, | |||||
this.inorderCount, | |||||
); | |||||
factory HomeGoodsModel.fromJson(Map<String, dynamic> srcJson) => | |||||
_$HomeGoodsModelFromJson(srcJson); | |||||
Map<String, dynamic> toJson() => _$HomeGoodsModelToJson(this); | |||||
} |
@@ -0,0 +1,36 @@ | |||||
// GENERATED CODE - DO NOT MODIFY BY HAND | |||||
part of 'home_goods_model.dart'; | |||||
// ************************************************************************** | |||||
// JsonSerializableGenerator | |||||
// ************************************************************************** | |||||
HomeGoodsModel _$HomeGoodsModelFromJson(Map<String, dynamic> json) { | |||||
return HomeGoodsModel( | |||||
json['provider_name'] as String, | |||||
json['good_id'] as String, | |||||
json['good_image'] as String, | |||||
json['good_title'] as String, | |||||
json['shop_name'] as String, | |||||
json['coupon'] as String, | |||||
json['commission'] as String, | |||||
json['market_price'] as String, | |||||
json['current_price'] as String, | |||||
json['inorder_count'] as String, | |||||
); | |||||
} | |||||
Map<String, dynamic> _$HomeGoodsModelToJson(HomeGoodsModel instance) => | |||||
<String, dynamic>{ | |||||
'provider_name': instance.providerName, | |||||
'good_id': instance.goodId, | |||||
'good_image': instance.goodImage, | |||||
'good_title': instance.goodTitle, | |||||
'shop_name': instance.shopName, | |||||
'coupon': instance.coupon, | |||||
'commission': instance.commission, | |||||
'market_price': instance.marketPrice, | |||||
'current_price': instance.currentPrice, | |||||
'inorder_count': instance.inorderCount, | |||||
}; |
@@ -0,0 +1,54 @@ | |||||
import 'package:json_annotation/json_annotation.dart'; | |||||
part 'home_goods_style_model.g.dart'; | |||||
@JsonSerializable() | |||||
class HomeGoodsStyleModel extends Object { | |||||
@JsonKey(name: 'provider_name_color') | |||||
String providerNameColor; | |||||
@JsonKey(name: 'provider_name_background_color') | |||||
String providerNameBackgroundColor; | |||||
@JsonKey(name: 'shop_name_color') | |||||
String shopNameColor; | |||||
@JsonKey(name: 'shop_icon') | |||||
String shopIcon; | |||||
@JsonKey(name: 'coupon_background_color') | |||||
String couponBackgroundColor; | |||||
@JsonKey(name: 'coupon_font_color') | |||||
String couponFontColor; | |||||
@JsonKey(name: 'commission_background_color') | |||||
String commissionBackgroundColor; | |||||
@JsonKey(name: 'commission_font_color') | |||||
String commissionFontColor; | |||||
@JsonKey(name: 'market_price_color') | |||||
String marketPriceColor; | |||||
@JsonKey(name: 'current_price_color') | |||||
String currentPriceColor; | |||||
HomeGoodsStyleModel( | |||||
this.providerNameColor, | |||||
this.providerNameBackgroundColor, | |||||
this.shopNameColor, | |||||
this.shopIcon, | |||||
this.couponBackgroundColor, | |||||
this.couponFontColor, | |||||
this.commissionBackgroundColor, | |||||
this.commissionFontColor, | |||||
this.marketPriceColor, | |||||
this.currentPriceColor, | |||||
); | |||||
factory HomeGoodsStyleModel.fromJson(Map<String, dynamic> srcJson) => | |||||
_$HomeGoodsStyleModelFromJson(srcJson); | |||||
Map<String, dynamic> toJson() => _$HomeGoodsStyleModelToJson(this); | |||||
} |
@@ -0,0 +1,37 @@ | |||||
// GENERATED CODE - DO NOT MODIFY BY HAND | |||||
part of 'home_goods_style_model.dart'; | |||||
// ************************************************************************** | |||||
// JsonSerializableGenerator | |||||
// ************************************************************************** | |||||
HomeGoodsStyleModel _$HomeGoodsStyleModelFromJson(Map<String, dynamic> json) { | |||||
return HomeGoodsStyleModel( | |||||
json['provider_name_color'] as String, | |||||
json['provider_name_background_color'] as String, | |||||
json['shop_name_color'] as String, | |||||
json['shop_icon'] as String, | |||||
json['coupon_background_color'] as String, | |||||
json['coupon_font_color'] as String, | |||||
json['commission_background_color'] as String, | |||||
json['commission_font_color'] as String, | |||||
json['market_price_color'] as String, | |||||
json['current_price_color'] as String, | |||||
); | |||||
} | |||||
Map<String, dynamic> _$HomeGoodsStyleModelToJson( | |||||
HomeGoodsStyleModel instance) => | |||||
<String, dynamic>{ | |||||
'provider_name_color': instance.providerNameColor, | |||||
'provider_name_background_color': instance.providerNameBackgroundColor, | |||||
'shop_name_color': instance.shopNameColor, | |||||
'shop_icon': instance.shopIcon, | |||||
'coupon_background_color': instance.couponBackgroundColor, | |||||
'coupon_font_color': instance.couponFontColor, | |||||
'commission_background_color': instance.commissionBackgroundColor, | |||||
'commission_font_color': instance.commissionFontColor, | |||||
'MarketPriceColor': instance.marketPriceColor, | |||||
'current_price_color': instance.currentPriceColor, | |||||
}; |
@@ -1,13 +1,11 @@ | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:shimmer/shimmer.dart'; | import 'package:shimmer/shimmer.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home_banner/home_banner_sk.dart'; | |||||
class HomeGoodsHeaderSkeletonDelegate extends SliverPersistentHeaderDelegate { | |||||
HomeGoodsHeaderSkeletonDelegate(); | |||||
class HomeGoodsHeaderSkeleton extends StatelessWidget { | |||||
const HomeGoodsHeaderSkeleton({Key key}) : super(key: key); | |||||
@override | @override | ||||
Widget build( | |||||
BuildContext context, double shrinkOffset, bool overlapsContent) { | |||||
Widget build(BuildContext context) { | |||||
return Container( | return Container( | ||||
width: double.infinity, | width: double.infinity, | ||||
height: double.infinity, | height: double.infinity, | ||||
@@ -48,14 +46,4 @@ class HomeGoodsHeaderSkeletonDelegate extends SliverPersistentHeaderDelegate { | |||||
), | ), | ||||
); | ); | ||||
} | } | ||||
@override | |||||
double get maxExtent => 64.0; | |||||
@override | |||||
double get minExtent => 64.0; | |||||
@override | |||||
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => | |||||
false; // 如果内容需要更新,设置为true | |||||
} | } |
@@ -25,6 +25,10 @@ dev_dependencies: | |||||
zhiying_comm: | zhiying_comm: | ||||
path: ../zhiying_comm | path: ../zhiying_comm | ||||
json_serializable: ^3.3.0 | |||||
build_runner: ^1.10.0 | |||||
# For information on the generic Dart part of this file, see the | # For information on the generic Dart part of this file, see the | ||||
# following page: https://dart.dev/tools/pub/pubspec | # following page: https://dart.dev/tools/pub/pubspec | ||||
@@ -55,17 +59,13 @@ flutter: | |||||
# "family" key with the font family name, and a "fonts" key with a | # "family" key with the font family name, and a "fonts" key with a | ||||
# list giving the asset and other descriptors for the font. For | # list giving the asset and other descriptors for the font. For | ||||
# example: | # example: | ||||
# fonts: | |||||
# - family: Schyler | |||||
# fonts: | |||||
# - asset: fonts/Schyler-Regular.ttf | |||||
# - asset: fonts/Schyler-Italic.ttf | |||||
# style: italic | |||||
# - family: Trajan Pro | |||||
# fonts: | |||||
# - asset: fonts/TrajanPro.ttf | |||||
# - asset: fonts/TrajanPro_Bold.ttf | |||||
# weight: 700 | |||||
fonts: | |||||
- family: Din | |||||
fonts: | |||||
- asset: assets/fonts/DIN-Bold.otf | |||||
- asset: assets/fonts/DIN-Medium.otf | |||||
- asset: assets/fonts/DIN-Regular.otf | |||||
# | # | ||||
# For details regarding fonts in packages, see | # For details regarding fonts in packages, see | ||||
# https://flutter.dev/custom-fonts/#from-packages | # https://flutter.dev/custom-fonts/#from-packages |