diff --git a/lib/pages/login_page/bloc/bloc.dart b/lib/pages/login_page/bloc/bloc.dart new file mode 100644 index 0000000..9111e4e --- /dev/null +++ b/lib/pages/login_page/bloc/bloc.dart @@ -0,0 +1,3 @@ +export 'login_bloc.dart'; +export 'login_event.dart'; +export 'login_state.dart'; \ No newline at end of file diff --git a/lib/pages/login_page/bloc/login_bloc.dart b/lib/pages/login_page/bloc/login_bloc.dart new file mode 100644 index 0000000..3d46804 --- /dev/null +++ b/lib/pages/login_page/bloc/login_bloc.dart @@ -0,0 +1,15 @@ +import 'dart:async'; +import 'package:bloc/bloc.dart'; +import './bloc.dart'; + +class LoginBloc extends Bloc { + @override + LoginState get initialState => InitialLoginState(); + + @override + Stream mapEventToState( + LoginEvent event, + ) async* { + // TODO: Add Logic + } +} diff --git a/lib/pages/login_page/bloc/login_event.dart b/lib/pages/login_page/bloc/login_event.dart new file mode 100644 index 0000000..7883b15 --- /dev/null +++ b/lib/pages/login_page/bloc/login_event.dart @@ -0,0 +1,10 @@ +import 'package:equatable/equatable.dart'; + +abstract class LoginEvent extends Equatable { + const LoginEvent(); + @override + List get props => []; +} + +/// 初始化 +class LoginInitEvent extends LoginEvent{} diff --git a/lib/pages/login_page/bloc/login_repository.dart b/lib/pages/login_page/bloc/login_repository.dart new file mode 100644 index 0000000..e8401a5 --- /dev/null +++ b/lib/pages/login_page/bloc/login_repository.dart @@ -0,0 +1,19 @@ + +import 'package:zhiying_comm/util/net_util.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +class LoginRepository{ + + /// 获取页面数据 + Future fetchNetPageData() async{ + + } + + /// 获取缓存的页面数据 + Future fetchCachePageData() async{ + + } + + + +} \ No newline at end of file diff --git a/lib/pages/login_page/bloc/login_state.dart b/lib/pages/login_page/bloc/login_state.dart new file mode 100644 index 0000000..8c56b3d --- /dev/null +++ b/lib/pages/login_page/bloc/login_state.dart @@ -0,0 +1,10 @@ +import 'package:equatable/equatable.dart'; + +abstract class LoginState extends Equatable { + const LoginState(); +} + +class InitialLoginState extends LoginState { + @override + List get props => []; +} diff --git a/lib/pages/login_page/login_page.dart b/lib/pages/login_page/login_page.dart new file mode 100644 index 0000000..805c083 --- /dev/null +++ b/lib/pages/login_page/login_page.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:zhiying_base_widget/pages/login_page/bloc/bloc.dart'; +import 'package:zhiying_base_widget/pages/login_page/bloc/login_bloc.dart'; + +/// +/// 登陆页面 +/// +class LoginPage extends StatelessWidget { + + final Map data; + LoginPage(this.data, {Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: BlocProvider( + create: (_) => LoginBloc()..add(LoginInitEvent()), + child: SafeArea( + child: LoginPageContainer(), + ), + ), + ); + } +} + +class LoginPageContainer extends StatefulWidget { + @override + _LoginPageContainerState createState() => _LoginPageContainerState(); +} + +class _LoginPageContainerState extends State { + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/lib/register.dart b/lib/register.dart index 7e58762..77ac3d9 100644 --- a/lib/register.dart +++ b/lib/register.dart @@ -1,11 +1,10 @@ import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; +import 'package:zhiying_base_widget/pages/login_page/login_page.dart'; import 'package:zhiying_base_widget/pages/main_page/main_page.dart'; -import 'package:zhiying_base_widget/pages/mine_page//mine_page.dart'; import 'package:zhiying_base_widget/widgets/home_banner/home_banner_creater.dart'; import 'package:zhiying_base_widget/widgets/home_goods/home_goods_creater.dart'; import 'package:zhiying_base_widget/widgets/home_quick_entry/home_quick_entry_creater.dart'; -import 'package:zhiying_base_widget/widgets/mine_header/mine_header_creater.dart'; -import 'package:zhiying_base_widget/widgets/others/mine_header_bg_creater.dart'; +import 'package:zhiying_base_widget/widgets/home_slide_banner/home_slide_banner_creater.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; class BaseWidgetRegister { @@ -19,16 +18,26 @@ class BaseWidgetRegister { static void registPage() { PageFactory.regist('homePage', (model) => HomePage()); PageFactory.regist('index', (model) => MainPage(model)); - PageFactory.regist('homePage', (profile) => MinePage()); + PageFactory.regist('login', (model) => LoginPage(model)); } // 注册控件 static void registWidgets() { - WidgetFactory.regist('index_carousel', HomeBannerCreater()); + // ==================== 首页 + /// 可滚动banner + WidgetFactory.regist('index_carousel', HomeSlideBannerCreater()); WidgetFactory.regist('index_recommend_list', GoodsListCreater()); // 首页快速入口 WidgetFactory.regist('home_quick_entry', HomeQuickEntryCreater()); - // 个人中心 + + /// 首页快速入口 + WidgetFactory.regist('multi_nav', HomeQuickEntryCreater()); + + /// 不可以滚动banner + WidgetFactory.regist('index_banner_one', HomeBannerCreater()); + WidgetFactory.regist('index_banner_two', HomeBannerCreater()); + + // ==================== 个人中心 // WidgetFactory.regist('index_title', MineHeaderCreater()); // WidgetFactory.regist('index_search', MineHeaderBgCreater()); // WidgetFactory.regist('index_search', MineQuickEntryCreater()); diff --git a/lib/widgets/home_banner/bloc/bloc.dart b/lib/widgets/home_banner/bloc/bloc.dart new file mode 100644 index 0000000..c819a96 --- /dev/null +++ b/lib/widgets/home_banner/bloc/bloc.dart @@ -0,0 +1,3 @@ +export 'home_banner_bloc.dart'; +export 'home_banner_event.dart'; +export 'home_banner_state.dart'; \ No newline at end of file diff --git a/lib/widgets/home_banner/bloc/home_banner_bloc.dart b/lib/widgets/home_banner/bloc/home_banner_bloc.dart new file mode 100644 index 0000000..c36ad57 --- /dev/null +++ b/lib/widgets/home_banner/bloc/home_banner_bloc.dart @@ -0,0 +1,36 @@ +import 'dart:async'; +import 'package:bloc/bloc.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:zhiying_base_widget/widgets/home_banner/bloc/home_banner_repository.dart'; +import './bloc.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +class HomeBannerBloc extends Bloc { + HomeBannerRepository repository; + + HomeBannerBloc({@required this.repository}); + + @override + HomeBannerState get initialState => InitialHomeBannerState(); + + @override + Stream mapEventToState( + HomeBannerEvent event, + ) async* { + final currentState = state; + if (event is HomeBannerInitEvent) { + yield* _mapHomeBannerInitEventToState(event); + } + } + + /// 初始化 + Stream _mapHomeBannerInitEventToState(HomeBannerInitEvent event) async* { + var cache = await repository.fetchCacheData(modId: event.model['mod_id']); + if (!EmptyUtil.isEmpty(cache)) yield HomeBannerCacheState(); + var result = await repository.fetchNetData(modId: event.model['mod_id']); + if (!EmptyUtil.isEmpty(result)) + yield HomeBannerLoadedState(); + else + yield HomeBannerErrorState(); + } +} diff --git a/lib/widgets/home_banner/bloc/home_banner_event.dart b/lib/widgets/home_banner/bloc/home_banner_event.dart new file mode 100644 index 0000000..0068b70 --- /dev/null +++ b/lib/widgets/home_banner/bloc/home_banner_event.dart @@ -0,0 +1,17 @@ +import 'package:equatable/equatable.dart'; + +abstract class HomeBannerEvent extends Equatable { + const HomeBannerEvent(); +} + +/// +/// 初始化事件 +/// +class HomeBannerInitEvent extends HomeBannerEvent { + final Map model; + + const HomeBannerInitEvent(this.model); + + @override + List get props => []; +} diff --git a/lib/widgets/home_banner/bloc/home_banner_repository.dart b/lib/widgets/home_banner/bloc/home_banner_repository.dart new file mode 100644 index 0000000..89292b3 --- /dev/null +++ b/lib/widgets/home_banner/bloc/home_banner_repository.dart @@ -0,0 +1,24 @@ +import 'package:flutter/cupertino.dart'; +import 'package:zhiying_base_widget/widgets/home_banner/model/HomeBannerModel.dart'; +import 'package:zhiying_comm/util/net_util.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +class HomeBannerRepository { + /// 读取缓存数据 + Future fetchCacheData({@required int modId}) async { + var reult = await NetUtil.getRequestCachedData('/api/v1/mod', params: {'ids': [modId]}); + if (!EmptyUtil.isEmpty(reult)) { + return HomeBannerModel(); + } + return null; + } + + /// 获取网路数据 + Future fetchNetData({@required int modId}) async { + var result = await NetUtil.post('/api/v1/mod', params: {'ids': [modId]}); + if (NetUtil.isSuccess(result)) { + return HomeBannerModel(); + } + return null; + } +} diff --git a/lib/widgets/home_banner/bloc/home_banner_state.dart b/lib/widgets/home_banner/bloc/home_banner_state.dart new file mode 100644 index 0000000..f056e95 --- /dev/null +++ b/lib/widgets/home_banner/bloc/home_banner_state.dart @@ -0,0 +1,29 @@ +import 'package:equatable/equatable.dart'; + +abstract class HomeBannerState extends Equatable { + const HomeBannerState(); +} + +/// 初始化状态 +class InitialHomeBannerState extends HomeBannerState { + @override + List get props => []; +} + +/// 数据加载完毕状态 +class HomeBannerLoadedState extends HomeBannerState { + @override + List get props => []; +} + +/// 缓存数据加载完毕 +class HomeBannerCacheState extends HomeBannerState { + @override + List get props => []; +} + +/// 数据加载失败 +class HomeBannerErrorState extends HomeBannerState { + @override + List get props => []; +} diff --git a/lib/widgets/home_banner/home_banner.dart b/lib/widgets/home_banner/home_banner.dart deleted file mode 100644 index 43cf13e..0000000 --- a/lib/widgets/home_banner/home_banner.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:zhiying_comm/zhiying_comm.dart'; -import 'package:flutter_swiper/flutter_swiper.dart'; - -class HomeBanner extends StatelessWidget { - final Map model; - - const HomeBanner(this.model, {Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: double.infinity, - height: 200, - child: Swiper( - itemBuilder: (BuildContext context, int index) { - // return new Image.network( - // "http://via.placeholder.com/350x150", - // fit: BoxFit.fill, - // ); - return Container(); - }, - itemCount: 3, - pagination: new SwiperPagination(), - control: new SwiperControl(), - onTap: (index) { - print(model.toString()); - }, - ), - ); - } -} diff --git a/lib/widgets/home_banner/home_banner_creater.dart b/lib/widgets/home_banner/home_banner_creater.dart index faf58a4..187932e 100644 --- a/lib/widgets/home_banner/home_banner_creater.dart +++ b/lib/widgets/home_banner/home_banner_creater.dart @@ -1,16 +1,15 @@ -import 'package:flutter/material.dart'; -import 'package:zhiying_base_widget/widgets/home_banner/home_banner.dart'; -import 'package:zhiying_base_widget/widgets/home_banner/home_banner_sk.dart'; + +import 'package:flutter/src/widgets/framework.dart'; +import 'package:zhiying_base_widget/widgets/home_banner/home_banner_widget.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; -class HomeBannerCreater extends WidgetCreater { - @override - List createSkeleton(Map model) { - return [HomeBannerSkeleton()]; - } +/// +/// 不可滚动Banner +/// +class HomeBannerCreater extends WidgetCreater{ @override List createWidgets(Map model) { - return [HomeBanner(model)]; + return [HomeBannerWidget(model)]; } -} +} \ No newline at end of file diff --git a/lib/widgets/home_banner/home_banner_sk.dart b/lib/widgets/home_banner/home_banner_sk.dart index 821a6ca..186fc6c 100644 --- a/lib/widgets/home_banner/home_banner_sk.dart +++ b/lib/widgets/home_banner/home_banner_sk.dart @@ -1,23 +1,83 @@ import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; class HomeBannerSkeleton extends StatelessWidget { + final Map model; + + const HomeBannerSkeleton(this.model); + @override Widget build(BuildContext context) { return Container( + height: 60, width: double.infinity, - height: 200, color: Colors.white, - child: Shimmer.fromColors( - baseColor: Colors.grey[300], - highlightColor: Colors.grey[100], - child: Container( - margin: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(10))), - ), - ), + child: _styleWidget(EmptyUtil.isEmpty(model) ? 1 : model.containsKey('mod_name') ? _getCount(model['mod_name']) : 1), + ); + } + + int _getCount(String modName) { + if (!EmptyUtil.isEmpty(modName)) { + if (modName.endsWith('one')) { + return 1; + } + if (modName.endsWith('two')) { + return 2; + } + if (modName.endsWith('three')) { + return 3; + } + if (modName.endsWith('four')) { + return 4; + } + if (modName.endsWith('five')) { + return 5; + } + } + + return 1; + } + + + Widget _styleWidget(int size) { + List data = []; + for(int i = 0 ; i < size; i++){ + data.add(i); + } + return Row( + children: data.map((index){ + var margin; + +// if(index == 0 && size !=1){ +// margin = const EdgeInsets.only(right: 10,); +// }else if(index == size -1 && size != 2 && size != 1){ +// margin = const EdgeInsets.only(left: 10); +// }else{ +// margin = const EdgeInsets.only(left: 10, right: 10); +// } + + margin = const EdgeInsets.only(left: 10, right: 10); + + + return Flexible( + flex: 1, + child: Shimmer.fromColors( + baseColor: Colors.grey[300], + highlightColor: Colors.grey[100], + child: Container( + height: double.infinity, + width: double.infinity, + margin: margin, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(7.5), + ), + ), + ), + ); + }).toList(), ); } + } diff --git a/lib/widgets/home_banner/home_banner_widget.dart b/lib/widgets/home_banner/home_banner_widget.dart new file mode 100644 index 0000000..ea8a928 --- /dev/null +++ b/lib/widgets/home_banner/home_banner_widget.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:zhiying_base_widget/widgets/home_banner/bloc/bloc.dart'; +import 'package:zhiying_base_widget/widgets/home_banner/bloc/home_banner_repository.dart'; +import 'package:zhiying_base_widget/widgets/home_banner/home_banner_sk.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +/// +/// 不可以滚动Banner +/// +class HomeBannerWidget extends StatefulWidget { + final Map model; + + const HomeBannerWidget(this.model); + + @override + _HomeBannerWidgetState createState() => _HomeBannerWidgetState(); +} + +class _HomeBannerWidgetState extends State { + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (_) => HomeBannerBloc(repository: HomeBannerRepository())..add(HomeBannerInitEvent(widget.model)), + child: HomeBannerContainer( + model: widget.model, + ), + ); + } +} + +class HomeBannerContainer extends StatefulWidget { + final Map model; + + const HomeBannerContainer({@required this.model}); + + @override + _HomeBannerContainerState createState() => _HomeBannerContainerState(); +} + +class _HomeBannerContainerState extends State { + @override + Widget build(BuildContext context) { + return BlocConsumer( + listener: (context, state) {}, + buildWhen: (previous, current) { + if (current is HomeBannerErrorState) { + return false; + } + return true; + }, + builder: (context, state) { + + print(state); + if (state is HomeBannerLoadedState) { + return ItemWidget(data: [1,2,3],); + } + if (state is HomeBannerCacheState) { + return ItemWidget(data: [1,2],); + } + + return HomeBannerSkeleton(widget.model); + }, + ); + } +} + +class ItemWidget extends StatelessWidget { + + final List data; + ItemWidget({this.data}); + + @override + Widget build(BuildContext context) { + return Container( + height: 180.h, + margin: EdgeInsets.only(top: 7.5, left: 2.5, right: 2.5), + child: Row( + children:data.map((index){ + return Flexible( + flex: 1, + child: Container( + margin: EdgeInsets.only( left: 5, right: 5), + decoration: BoxDecoration( + color: Colors.lightBlue, + borderRadius: BorderRadius.circular(7.5) + ), + ), + ); + }).toList(), + ), + ); + } +} + diff --git a/lib/widgets/home_banner/model/HomeBannerModel.dart b/lib/widgets/home_banner/model/HomeBannerModel.dart new file mode 100644 index 0000000..6ffa33e --- /dev/null +++ b/lib/widgets/home_banner/model/HomeBannerModel.dart @@ -0,0 +1,4 @@ + +class HomeBannerModel{ + +} \ No newline at end of file diff --git a/lib/widgets/home_quick_entry/bloc/bloc.dart b/lib/widgets/home_quick_entry/bloc/bloc.dart new file mode 100644 index 0000000..31646ba --- /dev/null +++ b/lib/widgets/home_quick_entry/bloc/bloc.dart @@ -0,0 +1,3 @@ +export 'home_quick_entry_bloc.dart'; +export 'home_quick_entry_event.dart'; +export 'home_quick_entry_state.dart'; \ No newline at end of file diff --git a/lib/widgets/home_quick_entry/bloc/home_quick_entry_bloc.dart b/lib/widgets/home_quick_entry/bloc/home_quick_entry_bloc.dart new file mode 100644 index 0000000..76fc8d9 --- /dev/null +++ b/lib/widgets/home_quick_entry/bloc/home_quick_entry_bloc.dart @@ -0,0 +1,38 @@ +import 'dart:async'; +import 'package:bloc/bloc.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:zhiying_base_widget/widgets/home_quick_entry/bloc/home_quick_entry_repository.dart'; +import './bloc.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +class HomeQuickEntryBloc extends Bloc { + HomeQuickEntryRepository repository; + + HomeQuickEntryBloc({@required this.repository}); + + @override + HomeQuickEntryState get initialState => InitialHomeQuickEntryState(); + + @override + Stream mapEventToState(HomeQuickEntryEvent event) async* { + final currentState = state; + if (event is HomeQuickEntryInitEvent) { + yield* _mapHomeQuickEntryInitToState(event); + } + } + + /// 初始化 + Stream _mapHomeQuickEntryInitToState(HomeQuickEntryInitEvent event) async* { + /// 获取缓存数据 + var cached = await repository.fetchCachedData(); + if (!EmptyUtil.isEmpty(cached)) { + yield HomeQuickEntryCachedState(); + } + var result = await repository.fetchData(); + if (!EmptyUtil.isEmpty(result)) { + yield HomeQuickEntryLoadedState(); + } else { + yield HomeQuickEntryErrorState(); + } + } +} diff --git a/lib/widgets/home_quick_entry/bloc/home_quick_entry_event.dart b/lib/widgets/home_quick_entry/bloc/home_quick_entry_event.dart new file mode 100644 index 0000000..9f050d7 --- /dev/null +++ b/lib/widgets/home_quick_entry/bloc/home_quick_entry_event.dart @@ -0,0 +1,11 @@ +import 'package:equatable/equatable.dart'; + +abstract class HomeQuickEntryEvent extends Equatable { + const HomeQuickEntryEvent(); + + @override + List get props => []; +} + +/// 初始事件 +class HomeQuickEntryInitEvent extends HomeQuickEntryEvent {} diff --git a/lib/widgets/home_quick_entry/bloc/home_quick_entry_repository.dart b/lib/widgets/home_quick_entry/bloc/home_quick_entry_repository.dart new file mode 100644 index 0000000..bec6cb3 --- /dev/null +++ b/lib/widgets/home_quick_entry/bloc/home_quick_entry_repository.dart @@ -0,0 +1,24 @@ +import 'package:zhiying_comm/util/net_util.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +class HomeQuickEntryRepository { + + /// 获取数据 + Future fetchData() async { + var result = await NetUtil.post('/api/v1/mod', params: {'ids':[7]}); + if(NetUtil.isSuccess(result)){ + + } + return null; + } + + /// 获取缓存数据 + Future fetchCachedData() async{ + var result = await NetUtil.getRequestCachedData('/api/v1/mod', params: {'ids':[7]}); + if(!EmptyUtil.isEmpty(result)){ + return result; + } + return null; + } + +} diff --git a/lib/widgets/home_quick_entry/bloc/home_quick_entry_state.dart b/lib/widgets/home_quick_entry/bloc/home_quick_entry_state.dart new file mode 100644 index 0000000..cd3b5e0 --- /dev/null +++ b/lib/widgets/home_quick_entry/bloc/home_quick_entry_state.dart @@ -0,0 +1,23 @@ +import 'package:equatable/equatable.dart'; + +abstract class HomeQuickEntryState extends Equatable { + const HomeQuickEntryState(); + + @override + List get props => []; +} + +/// 初始化状态 +class InitialHomeQuickEntryState extends HomeQuickEntryState { + @override + List get props => []; +} + +/// 加载数据完毕 +class HomeQuickEntryLoadedState extends HomeQuickEntryState {} + +/// 加载缓存数据 +class HomeQuickEntryCachedState extends HomeQuickEntryState {} + +/// 加载数据出错 +class HomeQuickEntryErrorState extends HomeQuickEntryState {} diff --git a/lib/widgets/home_quick_entry/home_quick_entry_creater.dart b/lib/widgets/home_quick_entry/home_quick_entry_creater.dart index dc262fd..dbbbfd1 100644 --- a/lib/widgets/home_quick_entry/home_quick_entry_creater.dart +++ b/lib/widgets/home_quick_entry/home_quick_entry_creater.dart @@ -1,10 +1,12 @@ import 'package:flutter/src/widgets/framework.dart'; -import 'package:zhiying_base_widget/widgets/home_quick_entry/home_quick_entry.dart'; -import 'package:zhiying_base_widget/widgets/home_quick_entry/home_quick_entry_sk.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; +import 'home_quick_entry_sk.dart'; +import 'home_quick_entry_widget.dart'; -class HomeQuickEntryCreater extends WidgetCreater{ - +/// +/// 快速入口 +/// +class HomeQuickEntryCreater extends WidgetCreater { @override List createSkeleton(Map model) { return [HomeQuickEntrySkeleton()]; @@ -14,6 +16,4 @@ class HomeQuickEntryCreater extends WidgetCreater{ List createWidgets(Map model) { return [HomeQuickEntryWidget()]; } - - -} \ No newline at end of file +} diff --git a/lib/widgets/home_quick_entry/home_quick_entry.dart b/lib/widgets/home_quick_entry/home_quick_entry_widget.dart similarity index 87% rename from lib/widgets/home_quick_entry/home_quick_entry.dart rename to lib/widgets/home_quick_entry/home_quick_entry_widget.dart index 21e8125..9ecab6a 100644 --- a/lib/widgets/home_quick_entry/home_quick_entry.dart +++ b/lib/widgets/home_quick_entry/home_quick_entry_widget.dart @@ -26,19 +26,19 @@ class HomeQuickEntryWidget extends StatelessWidget { : (data.length ~/ (rowSize * columSize)) + 1; double containerHeight = 145.h * ( data.length >= rowSize * columSize ? rowSize : (data.length / columSize).ceil()) + (rowSize == 1 ? 0 : 25.h); - double headHeight = 50.h ; +// double headHeight = 50.h ; return Container( margin: EdgeInsets.only(bottom: 25.h), - height: containerHeight + headHeight, + height: containerHeight ,//+ headHeight, width: double.infinity, child: Column( children: [ - Container( - margin: EdgeInsets.symmetric(horizontal: 25.w), - height: headHeight, - color: Colors.green, - ), +// Container( +// margin: EdgeInsets.symmetric(horizontal: 25.w), +// height: headHeight, +// color: Colors.green, +// ), Expanded( child: Swiper( itemHeight: 145.h, @@ -168,22 +168,29 @@ class HomeQuickEntryItem extends StatelessWidget { HomeQuickEntryItem({this.data}); + _itemOnClick(){ + + } + @override Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - // 图片 - MyNetWorkImage(), - SizedBox(height: 10.h), - Text( - '京东爆款$data', - style: - TextStyle(color: HexColor.fromHex('#666666'), fontSize: 20.sp), - ), + return GestureDetector( + onTap: () => _itemOnClick(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // 图片 + MyNetWorkImage(), + SizedBox(height: 10.h), + Text( + '京东爆款$data', + style: + TextStyle(color: HexColor.fromHex('#666666'), fontSize: 20.sp), + ), // SizedBox(height: 25.h,) - ], + ], + ), ); } } diff --git a/lib/widgets/home_quick_entry/model/home_quick_entry_model.dart b/lib/widgets/home_quick_entry/model/home_quick_entry_model.dart new file mode 100644 index 0000000..631d8e1 --- /dev/null +++ b/lib/widgets/home_quick_entry/model/home_quick_entry_model.dart @@ -0,0 +1,4 @@ + +class HomeQuickEntryModel{ + +} \ No newline at end of file diff --git a/lib/widgets/home_slide_banner/bloc/bloc.dart b/lib/widgets/home_slide_banner/bloc/bloc.dart new file mode 100644 index 0000000..b7f46ee --- /dev/null +++ b/lib/widgets/home_slide_banner/bloc/bloc.dart @@ -0,0 +1,3 @@ +export 'home_slide_banner_bloc.dart'; +export 'home_slide_banner_event.dart'; +export 'home_slide_banner_state.dart'; \ No newline at end of file diff --git a/lib/widgets/home_slide_banner/bloc/home_slide_banner_bloc.dart b/lib/widgets/home_slide_banner/bloc/home_slide_banner_bloc.dart new file mode 100644 index 0000000..694f4d8 --- /dev/null +++ b/lib/widgets/home_slide_banner/bloc/home_slide_banner_bloc.dart @@ -0,0 +1,39 @@ +import 'dart:async'; +import 'package:bloc/bloc.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:zhiying_base_widget/widgets/home_slide_banner/bloc/home_slide_banner_event.dart'; +import 'package:zhiying_base_widget/widgets/home_slide_banner/bloc/home_slide_banner_repository.dart'; +import 'package:zhiying_base_widget/widgets/home_slide_banner/bloc/home_slide_banner_state.dart'; +import './bloc.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +class HomeSlideBannerBloc extends Bloc { + HomeSlideBannerRepository repository; + + HomeSlideBannerBloc({@required this.repository}); + + @override + HomeSlideBannerState get initialState => InitialHomeSlideBannerState(); + + @override + Stream mapEventToState(HomeSlideBannerEvent event) async* { + final currentState = state; + + /// 初始化 + if (event is HomeBannerInitEvent) { + print('---------HomeBannerInitEvent---------'); + yield* _mapInitEventToState(event); + } + } + + /// 初始化 + Stream _mapInitEventToState(HomeBannerInitEvent event) async* { + var cached = await repository.fetchCachedDate(id: event.model['mod_id']); + if (!EmptyUtil.isEmpty(cached)) yield HomeSlideBannerCachedState(datas: cached); + var param = await repository.fetchData( id: event.model['mod_id']); + if (!EmptyUtil.isEmpty(param)) + yield HomeSlideBannerLoadedState(datas: param); + else + yield HomeSlideBannerLoadError(); + } +} diff --git a/lib/widgets/home_slide_banner/bloc/home_slide_banner_event.dart b/lib/widgets/home_slide_banner/bloc/home_slide_banner_event.dart new file mode 100644 index 0000000..ec7866c --- /dev/null +++ b/lib/widgets/home_slide_banner/bloc/home_slide_banner_event.dart @@ -0,0 +1,14 @@ +import 'package:equatable/equatable.dart'; + + +abstract class HomeSlideBannerEvent extends Equatable { + const HomeSlideBannerEvent(); + @override + List get props => []; +} + +/// 初始事件 +class HomeBannerInitEvent extends HomeSlideBannerEvent{ + final Map model; + const HomeBannerInitEvent({this.model}); +} diff --git a/lib/widgets/home_slide_banner/bloc/home_slide_banner_repository.dart b/lib/widgets/home_slide_banner/bloc/home_slide_banner_repository.dart new file mode 100644 index 0000000..4a2ac42 --- /dev/null +++ b/lib/widgets/home_slide_banner/bloc/home_slide_banner_repository.dart @@ -0,0 +1,34 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:zhiying_base_widget/widgets/home_slide_banner/model/home_slide_banner_model.dart'; +import 'package:zhiying_comm/util/net_util.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; +import 'package:zhiying_comm/util/global_config.dart'; + +class HomeSlideBannerRepository{ + + /// 获取缓存数据 + Future> fetchCachedDate({@required int id}) async{ + var cached = await NetUtil.getRequestCachedData('/api/v1/mod', params: {'ids': [id]}); + if(!EmptyUtil.isEmpty(cached)){ + HomeSlideBannerModel model = HomeSlideBannerModel.fromJson(cached); + if(null != model && !EmptyUtil.isEmpty(model.items)){ + return model.items; + } + } + return null; + } + + /// 获取数据 + Future> fetchData({@required int id}) async{ + var params = await NetUtil.post('/api/v1/mod', params: {'ids': [id]}); + if(!EmptyUtil.isEmpty(params) && NetUtil.isSuccess(params)){ + HomeSlideBannerModel model = HomeSlideBannerModel.fromJson(params[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); + if(null != model && !EmptyUtil.isEmpty(model.items)){ + return model.items; + } + } + return null; + } + +} diff --git a/lib/widgets/home_slide_banner/bloc/home_slide_banner_state.dart b/lib/widgets/home_slide_banner/bloc/home_slide_banner_state.dart new file mode 100644 index 0000000..122b4ef --- /dev/null +++ b/lib/widgets/home_slide_banner/bloc/home_slide_banner_state.dart @@ -0,0 +1,44 @@ +import 'package:equatable/equatable.dart'; +import 'package:zhiying_base_widget/widgets/home_slide_banner/model/home_slide_banner_model.dart'; + +abstract class HomeSlideBannerState extends Equatable { + const HomeSlideBannerState(); + + @override + List get props => []; +} + +/// 初始化状态 +class InitialHomeSlideBannerState extends HomeSlideBannerState { + @override + List get props => []; +} + +/// 缓存数据 +class HomeSlideBannerCachedState extends HomeSlideBannerState { + List datas; + + HomeSlideBannerCachedState({this.datas}); + + @override + List get props => [this.datas]; +} + +/// 数据加载完毕状态 +class HomeSlideBannerLoadedState extends HomeSlideBannerState { + List datas; + + HomeSlideBannerLoadedState({this.datas}); + + HomeSlideBannerLoadedState copyWith({List newData}) { + return HomeSlideBannerLoadedState( + datas: newData ?? datas, + ); + } + + @override + List get props => [datas]; +} + +/// 数据加载失败 +class HomeSlideBannerLoadError extends HomeSlideBannerState {} diff --git a/lib/widgets/home_slide_banner/home_slide_banner.dart b/lib/widgets/home_slide_banner/home_slide_banner.dart new file mode 100644 index 0000000..6212134 --- /dev/null +++ b/lib/widgets/home_slide_banner/home_slide_banner.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_swiper/flutter_swiper.dart'; +import 'bloc/bloc.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +import 'bloc/home_slide_banner_repository.dart'; +import 'home_slide_banner_sk.dart'; +import 'model/home_slide_banner_model.dart'; + +/// +/// banner轮播图 +/// +class HomeSlideBanner extends StatefulWidget { + final Map model; + + const HomeSlideBanner(this.model, {Key key}) : super(key: key); + + @override + _HomeSlideBannerState createState() => _HomeSlideBannerState(); +} + +class _HomeSlideBannerState extends State { + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (_) => HomeSlideBannerBloc(repository: HomeSlideBannerRepository())..add(HomeBannerInitEvent(model: widget?.model)), + child: HomeSlideBannerContainer(), + ); + } +} + +class HomeSlideBannerContainer extends StatefulWidget { + @override + _HomeSlideBannerContainerState createState() => _HomeSlideBannerContainerState(); +} + +class _HomeSlideBannerContainerState extends State { + /// 子元素点击事件 + void _itemOnClick(HomeSlideBannerModelItems items) { + print('点击了 $items'); + } + + @override + Widget build(BuildContext context) { + return BlocConsumer( + listener: (BuildContext context, HomeSlideBannerState state) { + if (state is HomeSlideBannerLoadError) { + print('数据加载出错'); + } + }, + buildWhen: (previous, current) { + /// 数据加载出错不进行build + if (current is HomeSlideBannerLoadError) { + return false; + } + return true; + }, + builder: (context, state) { + print('currente state = $state'); + if (state is HomeSlideBannerLoadedState) { + return _getMainWidget(state.datas); + } + if (state is HomeSlideBannerCachedState) { + return _getMainWidget(state.datas); + } + // 骨架屏 + return HomeSlideBannerSkeleton(); + }, + ); + } + + Widget _getMainWidget(List datas) { + return Container( + width: double.infinity, + height: 400.h, + child: Swiper( + itemBuilder: (BuildContext context, int index) { + return Container( + color: Colors.green, + ); + }, + itemCount: datas?.length ?? 0, + onTap: (index) => _itemOnClick(datas[index]), + pagination: _SwiperCustomPagination(datas?.length ?? 0), + ), + ); + } + + // 自定义进度条 + SwiperPlugin _SwiperCustomPagination(int pageCount) { + List list = []; + for (int i = 0; i < pageCount; i++) { + list.add(i); + } + + return SwiperCustomPagination(builder: (BuildContext context, SwiperPluginConfig config) { + return Align( + alignment: Alignment(0.0, 0.9), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: list.map((index) { + var borderRadius; + if (index == 0) { + borderRadius = BorderRadius.only(topLeft: Radius.circular(2), bottomLeft: Radius.circular(2)); + } + if (index == list.length - 1) { + borderRadius = BorderRadius.only(topRight: Radius.circular(2), bottomRight: Radius.circular(2)); + } + + if (index == config.activeIndex) { + borderRadius = BorderRadius.all(Radius.circular(2)); + } + + return Container( + height: 4, + width: 25, + decoration: BoxDecoration( + borderRadius: borderRadius, color: index == config.activeIndex ? HexColor.fromHex('#FF4242') : HexColor.fromHex('#FFFFFF')), + ); + }).toList(), + ), + ); + }); + } +} diff --git a/lib/widgets/home_slide_banner/home_slide_banner_creater.dart b/lib/widgets/home_slide_banner/home_slide_banner_creater.dart new file mode 100644 index 0000000..421dba6 --- /dev/null +++ b/lib/widgets/home_slide_banner/home_slide_banner_creater.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; +import 'home_slide_banner.dart'; +import 'home_slide_banner_sk.dart'; + +/// +/// 可以滚动Banner +/// +class HomeSlideBannerCreater extends WidgetCreater { + @override + List createSkeleton(Map model) { + return [HomeSlideBannerSkeleton()]; + } + + @override + List createWidgets(Map model) { + return [HomeSlideBanner(model)]; + } +} diff --git a/lib/widgets/home_slide_banner/home_slide_banner_sk.dart b/lib/widgets/home_slide_banner/home_slide_banner_sk.dart new file mode 100644 index 0000000..fdb6da2 --- /dev/null +++ b/lib/widgets/home_slide_banner/home_slide_banner_sk.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:shimmer/shimmer.dart'; + +class HomeSlideBannerSkeleton extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: 200, + color: Colors.white, + child: Shimmer.fromColors( + baseColor: Colors.grey[300], + highlightColor: Colors.grey[100], + child: Container( + margin: EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(10))), + ), + ), + ); + } +} diff --git a/lib/widgets/home_slide_banner/model/home_slide_banner_model.dart b/lib/widgets/home_slide_banner/model/home_slide_banner_model.dart new file mode 100644 index 0000000..cdcda54 --- /dev/null +++ b/lib/widgets/home_slide_banner/model/home_slide_banner_model.dart @@ -0,0 +1,115 @@ +class HomeSlideBannerModel { + List items; + + HomeSlideBannerModel({this.items}); + + HomeSlideBannerModel.fromJson(Map json) { + if (json['6'] != null) { + items = new List(); + json['6'].forEach((v) { + items.add(new HomeSlideBannerModelItems.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.items != null) { + data['6'] = this.items.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class HomeSlideBannerModelItems { + String modId; + String modPid; + String modName; + String position; + String title; + String subtitle; + String url; + String margin; + String aspectRatio; + String icon; + String img; + String fontColor; + String bgImg; + String bgColor; + String bgColorT; + String badge; + String path; + String data; + String sort; + String isGlobal; + + HomeSlideBannerModelItems( + {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}); + + HomeSlideBannerModelItems.fromJson(Map json) { + modId = json['mod_id']?.toString(); + modPid = json['mod_pid']?.toString(); + modName = json['mod_name']?.toString(); + position = json['position']?.toString(); + title = json['title']?.toString(); + subtitle = json['subtitle']?.toString(); + url = json['url']?.toString(); + margin = json['margin']?.toString(); + aspectRatio = json['aspect_ratio']?.toString(); + icon = json['icon']?.toString(); + img = json['img']?.toString(); + fontColor = json['font_color']?.toString(); + bgImg = json['bg_img']?.toString(); + bgColor = json['bg_color']?.toString(); + bgColorT = json['bg_color_t']?.toString(); + badge = json['badge']?.toString(); + path = json['path']?.toString(); + data = json['data']?.toString(); + sort = json['sort']?.toString(); + isGlobal = json['is_global']?.toString(); + } + + Map toJson() { + final Map data = new Map(); + data['mod_id'] = this.modId; + data['mod_pid'] = this.modPid; + data['mod_name'] = this.modName; + data['position'] = this.position; + data['title'] = this.title; + data['subtitle'] = this.subtitle; + data['url'] = this.url; + data['margin'] = this.margin; + data['aspect_ratio'] = this.aspectRatio; + data['icon'] = this.icon; + data['img'] = this.img; + data['font_color'] = this.fontColor; + data['bg_img'] = this.bgImg; + data['bg_color'] = this.bgColor; + data['bg_color_t'] = this.bgColorT; + data['badge'] = this.badge; + data['path'] = this.path; + data['data'] = this.data; + data['sort'] = this.sort; + data['is_global'] = this.isGlobal; + return data; + } +}