@@ -4,7 +4,6 @@ import 'package:zhiying_base_widget/pages/wallet_page/wallet_page.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_widget.dart'; | import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_widget.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/home_quick_entry_creater.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_slide_banner/home_slide_banner_creater.dart'; | import 'package:zhiying_base_widget/widgets/home/home_slide_banner/home_slide_banner_creater.dart'; | ||||
import 'package:zhiying_base_widget/widgets/mine/mine_data/mine_data.dart'; | import 'package:zhiying_base_widget/widgets/mine/mine_data/mine_data.dart'; | ||||
import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header.dart'; | import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header.dart'; | ||||
@@ -18,6 +17,9 @@ import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income.d | |||||
import 'package:zhiying_comm/util/defalut_widget_creater.dart'; | import 'package:zhiying_comm/util/defalut_widget_creater.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'widgets/home/home_quick_entry/home_quick_entry.dart'; | |||||
class BaseWidgetRegister { | class BaseWidgetRegister { | ||||
/// 初始化方法 | /// 初始化方法 | ||||
static void init() { | static void init() { | ||||
@@ -51,12 +53,8 @@ class BaseWidgetRegister { | |||||
// /// 可滚动banner | // /// 可滚动banner | ||||
WidgetFactory.regist('index_carousel', HomeSlideBannerCreater()); | WidgetFactory.regist('index_carousel', HomeSlideBannerCreater()); | ||||
WidgetFactory.regist('index_recommend_list', GoodsListCreater()); | WidgetFactory.regist('index_recommend_list', GoodsListCreater()); | ||||
/// 首页快速入口 | |||||
WidgetFactory.regist('home_quick_entry', HomeQuickEntryCreater()); | |||||
// | |||||
// /// 首页快速入口 | // /// 首页快速入口 | ||||
WidgetFactory.regist('multi_nav', HomeQuickEntryCreater()); | |||||
WidgetFactory.regist('multi_nav', DefaultWidgetCreater((model) => HomeQuickEntry(model))); | |||||
// | // | ||||
// /// 不可以滚动banner | // /// 不可以滚动banner | ||||
WidgetFactory.regist('index_banner_one', HomeBannerCreater()); | WidgetFactory.regist('index_banner_one', HomeBannerCreater()); | ||||
@@ -64,26 +62,17 @@ class BaseWidgetRegister { | |||||
// ==================== 个人中心 | // ==================== 个人中心 | ||||
WidgetFactory.regist('profile_appbar', MineNavCreater()); | WidgetFactory.regist('profile_appbar', MineNavCreater()); | ||||
WidgetFactory.regist('profile_background', | |||||
DefaultWidgetCreater((model) => MineNavBg(model))); | |||||
WidgetFactory.regist( | |||||
'profile_header', DefaultWidgetCreater((model) => MineHeader(model))); | |||||
WidgetFactory.regist( | |||||
'profile_earning', DefaultWidgetCreater((model) => MineData(model))); | |||||
WidgetFactory.regist('profile_functions', | |||||
DefaultWidgetCreater((model) => MineQuickEntry(model))); | |||||
WidgetFactory.regist('profile_my_functions', | |||||
DefaultWidgetCreater((model) => MineQuickEntry(model))); | |||||
WidgetFactory.regist('profile_carousel', | |||||
DefaultWidgetCreater((model) => HomeBannerWidget(model))); | |||||
WidgetFactory.regist('profile_background', DefaultWidgetCreater((model) => MineNavBg(model))); | |||||
WidgetFactory.regist('profile_header', DefaultWidgetCreater((model) => MineHeader(model))); | |||||
WidgetFactory.regist('profile_earning', DefaultWidgetCreater((model) => MineData(model))); | |||||
WidgetFactory.regist('profile_functions', DefaultWidgetCreater((model) => MineQuickEntry(model))); | |||||
WidgetFactory.regist('profile_my_functions', DefaultWidgetCreater((model) => MineQuickEntry(model))); | |||||
WidgetFactory.regist('profile_carousel', DefaultWidgetCreater((model) => HomeBannerWidget(model))); | |||||
// ==================== 钱包 | // ==================== 钱包 | ||||
WidgetFactory.regist( | |||||
'wallet_data', DefaultWidgetCreater((model) => WalletData())); | |||||
WidgetFactory.regist( | |||||
'wallet_detail', DefaultWidgetCreater((model) => WalletDetail())); | |||||
WidgetFactory.regist('wallet_data', DefaultWidgetCreater((model) => WalletData())); | |||||
WidgetFactory.regist('wallet_detail', DefaultWidgetCreater((model) => WalletDetail())); | |||||
WidgetFactory.regist( | |||||
'wallet_income', DefaultWidgetCreater((model) => WalletIncome())); | |||||
WidgetFactory.regist('wallet_income', DefaultWidgetCreater((model) => WalletIncome())); | |||||
} | } | ||||
} | } |
@@ -26,13 +26,17 @@ class HomeBannerBloc extends Bloc<HomeBannerEvent, HomeBannerState> { | |||||
} | } | ||||
/// 初始化 | /// 初始化 | ||||
Stream<HomeBannerState> _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']); | |||||
Stream<HomeBannerState> _mapHomeBannerInitEventToState(HomeBannerInitEvent event) async* { | |||||
var parentData = await repository.fetchParentData(model: event.model); | |||||
if(!EmptyUtil.isEmpty(parentData)){ | |||||
yield HomeBannerLoadedState(model: parentData); | |||||
return; | |||||
} | |||||
var cache = await repository.fetchCacheData(model: event.model); | |||||
if (!EmptyUtil.isEmpty(cache)) yield HomeBannerCacheState(model: cache); | |||||
var result = await repository.fetchNetData(model: event.model); | |||||
if (!EmptyUtil.isEmpty(result)) | if (!EmptyUtil.isEmpty(result)) | ||||
yield HomeBannerLoadedState(); | |||||
yield HomeBannerLoadedState(model: result); | |||||
else | else | ||||
yield HomeBannerErrorState(); | yield HomeBannerErrorState(); | ||||
} | } | ||||
@@ -1,3 +1,5 @@ | |||||
import 'dart:convert'; | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_banner/model/HomeBannerModel.dart'; | import 'package:zhiying_base_widget/widgets/home/home_banner/model/HomeBannerModel.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
@@ -5,21 +7,37 @@ import 'package:zhiying_comm/util/net_util.dart'; | |||||
class HomeBannerRepository { | class HomeBannerRepository { | ||||
/// 读取缓存数据 | /// 读取缓存数据 | ||||
Future<HomeBannerModel> fetchCacheData({@required int modId}) async { | |||||
Future<HomeBannerModel> fetchCacheData({@required Map<String, dynamic> model}) async { | |||||
var result = await NetUtil.getRequestCachedData('/api/v1/mod', params: { | var result = await NetUtil.getRequestCachedData('/api/v1/mod', params: { | ||||
'ids': [modId] | |||||
'ids': [model['mod_id']] | |||||
}); | }); | ||||
if(NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])){ | if(NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])){ | ||||
return HomeBannerModel(); | |||||
return HomeBannerModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||||
} | |||||
return null; | |||||
} | |||||
/// 获取父类传进来的数据 | |||||
Future<HomeBannerModel> fetchParentData({@required Map<String, dynamic> model}) async{ | |||||
try { | |||||
String jsonInfo = model['data']; | |||||
if (!EmptyUtil.isEmpty(jsonInfo)) { | |||||
return HomeBannerModel.fromJson(jsonDecode(jsonInfo)); | |||||
} | |||||
}catch(e){ | |||||
Logger.log(e); | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
/// 获取网路数据 | /// 获取网路数据 | ||||
Future<HomeBannerModel> fetchNetData({@required int modId}) async { | |||||
var result = await NetUtil.post('/api/v1/mod', params: {'ids': [modId]}, cache: true); | |||||
Future<HomeBannerModel> fetchNetData({@required Map<String, dynamic> model}) async { | |||||
// print('请求 modId = $model['mod_id']'); | |||||
var result = await NetUtil.post('/api/v1/mod', params: {'ids': [model['mod_id']]}, cache: true); | |||||
if (NetUtil.isSuccess(result)) { | if (NetUtil.isSuccess(result)) { | ||||
return HomeBannerModel(); | |||||
return HomeBannerModel.fromJson(result); | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
@@ -1,4 +1,5 @@ | |||||
import 'package:equatable/equatable.dart'; | import 'package:equatable/equatable.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_banner/model/HomeBannerModel.dart'; | |||||
abstract class HomeBannerState extends Equatable { | abstract class HomeBannerState extends Equatable { | ||||
const HomeBannerState(); | const HomeBannerState(); | ||||
@@ -12,14 +13,22 @@ class InitialHomeBannerState extends HomeBannerState { | |||||
/// 数据加载完毕状态 | /// 数据加载完毕状态 | ||||
class HomeBannerLoadedState extends HomeBannerState { | class HomeBannerLoadedState extends HomeBannerState { | ||||
final HomeBannerModel model; | |||||
const HomeBannerLoadedState({this.model}); | |||||
@override | @override | ||||
List<Object> get props => []; | |||||
List<Object> get props => [this.model]; | |||||
} | } | ||||
/// 缓存数据加载完毕 | /// 缓存数据加载完毕 | ||||
class HomeBannerCacheState extends HomeBannerState { | class HomeBannerCacheState extends HomeBannerState { | ||||
final HomeBannerModel model; | |||||
const HomeBannerCacheState({this.model}); | |||||
@override | @override | ||||
List<Object> get props => []; | |||||
List<Object> get props => [this.model]; | |||||
} | } | ||||
/// 数据加载失败 | /// 数据加载失败 | ||||
@@ -11,6 +11,7 @@ class HomeBannerSkeleton extends StatelessWidget { | |||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Container( | return Container( | ||||
height: 60, | height: 60, | ||||
margin: const EdgeInsets.symmetric(vertical: 12.5), | |||||
width: double.infinity, | width: double.infinity, | ||||
color: Colors.white, | color: Colors.white, | ||||
child: _styleWidget(EmptyUtil.isEmpty(model) ? 1 : model.containsKey('mod_name') ? _getCount(model['mod_name']) : 1), | child: _styleWidget(EmptyUtil.isEmpty(model) ? 1 : model.containsKey('mod_name') ? _getCount(model['mod_name']) : 1), | ||||
@@ -48,18 +49,7 @@ class HomeBannerSkeleton extends StatelessWidget { | |||||
return Row( | return Row( | ||||
children: data.map((index){ | children: data.map((index){ | ||||
var margin; | 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); | margin = const EdgeInsets.only(left: 10, right: 10); | ||||
return Flexible( | return Flexible( | ||||
flex: 1, | flex: 1, | ||||
child: Shimmer.fromColors( | child: Shimmer.fromColors( | ||||
@@ -3,6 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_banner/bloc/bloc.dart'; | import 'package:zhiying_base_widget/widgets/home/home_banner/bloc/bloc.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_banner/bloc/home_banner_repository.dart'; | import 'package:zhiying_base_widget/widgets/home/home_banner/bloc/home_banner_repository.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_sk.dart'; | import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_sk.dart'; | ||||
import 'package:cached_network_image/cached_network_image.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_banner/model/HomeBannerModel.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
/// | /// | ||||
@@ -21,8 +23,7 @@ class _HomeBannerWidgetState extends State<HomeBannerWidget> { | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return BlocProvider<HomeBannerBloc>( | return BlocProvider<HomeBannerBloc>( | ||||
create: (_) => HomeBannerBloc(repository: HomeBannerRepository()) | |||||
..add(HomeBannerInitEvent(widget.model)), | |||||
create: (_) => HomeBannerBloc(repository: HomeBannerRepository())..add(HomeBannerInitEvent(widget.model)), | |||||
child: HomeBannerContainer( | child: HomeBannerContainer( | ||||
model: widget.model, | model: widget.model, | ||||
), | ), | ||||
@@ -40,6 +41,12 @@ class HomeBannerContainer extends StatefulWidget { | |||||
} | } | ||||
class _HomeBannerContainerState extends State<HomeBannerContainer> { | class _HomeBannerContainerState extends State<HomeBannerContainer> { | ||||
/// 点击事件 | |||||
void _itemOnClick(HomeBannerListItemModel model){ | |||||
print('${model?.skip_identifier}'); | |||||
} | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return BlocConsumer<HomeBannerBloc, HomeBannerState>( | return BlocConsumer<HomeBannerBloc, HomeBannerState>( | ||||
@@ -53,45 +60,57 @@ class _HomeBannerContainerState extends State<HomeBannerContainer> { | |||||
builder: (context, state) { | builder: (context, state) { | ||||
print(state); | print(state); | ||||
if (state is HomeBannerLoadedState) { | if (state is HomeBannerLoadedState) { | ||||
return ItemWidget( | |||||
data: [1, 2, 3], | |||||
); | |||||
int lenght = state?.model?.list?.length ?? 0; | |||||
if(lenght > 0) | |||||
return _getMainWidget(data: state?.model?.list); | |||||
else | |||||
return HomeBannerSkeleton(widget?.model); | |||||
} | } | ||||
if (state is HomeBannerCacheState) { | if (state is HomeBannerCacheState) { | ||||
return ItemWidget( | |||||
data: [1, 2], | |||||
); | |||||
int lenght = state?.model?.list?.length ?? 0; | |||||
if(lenght > 0) | |||||
return _getMainWidget(data: state?.model?.list); | |||||
else | |||||
return HomeBannerSkeleton(widget?.model); | |||||
} | } | ||||
return HomeBannerSkeleton(widget.model); | return HomeBannerSkeleton(widget.model); | ||||
}, | }, | ||||
); | ); | ||||
} | } | ||||
} | |||||
class ItemWidget extends StatelessWidget { | |||||
final List data; | |||||
ItemWidget({this.data}); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
/// 获取主要视图 | |||||
Widget _getMainWidget({List<HomeBannerListItemModel> data}){ | |||||
return Container( | return Container( | ||||
height: 180.h, | |||||
width: double.infinity, | |||||
margin: EdgeInsets.only(top: 7.5, left: 2.5, right: 2.5), | margin: EdgeInsets.only(top: 7.5, left: 2.5, right: 2.5), | ||||
child: Row( | child: Row( | ||||
children: data.map((index) { | |||||
children: data.map((model) { | |||||
return Flexible( | return Flexible( | ||||
flex: 1, | flex: 1, | ||||
child: Container( | |||||
margin: EdgeInsets.only(left: 5, right: 5), | |||||
decoration: BoxDecoration( | |||||
color: Colors.lightBlue, | |||||
borderRadius: BorderRadius.circular(7.5)), | |||||
child: GestureDetector( | |||||
behavior: HitTestBehavior.opaque, | |||||
onTap: ()=> _itemOnClick(model), | |||||
child: Container( | |||||
margin: EdgeInsets.only(left: 5, right: 5), | |||||
// decoration: BoxDecoration(color: Colors.lightBlue, borderRadius: BorderRadius.circular(7.5)), | |||||
child: CachedNetworkImage(imageUrl: model?.img), | |||||
), | |||||
), | ), | ||||
); | ); | ||||
}).toList(), | }).toList(), | ||||
), | ), | ||||
); | ); | ||||
} | } | ||||
} | } | ||||
// | |||||
// class ItemWidget extends StatelessWidget { | |||||
// final List<HomeBannerListItemModel> data; | |||||
// | |||||
// ItemWidget({this.data}); | |||||
// | |||||
// @override | |||||
// Widget build(BuildContext context) { | |||||
// | |||||
// } | |||||
// } |
@@ -1,4 +1,40 @@ | |||||
class HomeBannerModel { | |||||
List<HomeBannerListItemModel> list; | |||||
class HomeBannerModel{ | |||||
HomeBannerModel({this.list}); | |||||
} | |||||
factory HomeBannerModel.fromJson(Map<String, dynamic> json) { | |||||
return HomeBannerModel( | |||||
list: json['list'] != null ? (json['list'] as List).map((i) => HomeBannerListItemModel.fromJson(i)).toList() : null, | |||||
); | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
if (this.list != null) { | |||||
data['list'] = this.list.map((v) => v.toJson()).toList(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class HomeBannerListItemModel { | |||||
String img; | |||||
String skip_identifier; | |||||
HomeBannerListItemModel({this.img, this.skip_identifier}); | |||||
factory HomeBannerListItemModel.fromJson(Map<String, dynamic> json) { | |||||
return HomeBannerListItemModel( | |||||
img: json['img']?.toString(), | |||||
skip_identifier: json['skip_identifier']?.toString(), | |||||
); | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['img'] = this.img; | |||||
data['skip_identifier'] = this.skip_identifier; | |||||
return data; | |||||
} | |||||
} |
@@ -26,14 +26,22 @@ class HomeQuickEntryBloc extends Bloc<HomeQuickEntryEvent, HomeQuickEntryState> | |||||
/// 初始化 | /// 初始化 | ||||
Stream<HomeQuickEntryState> _mapHomeQuickEntryInitToState(HomeQuickEntryInitEvent event) async* { | Stream<HomeQuickEntryState> _mapHomeQuickEntryInitToState(HomeQuickEntryInitEvent event) async* { | ||||
/// 获取缓存数据 | |||||
/// 获取父页面传进来的数据 | |||||
var parentData = await repository.fetchPreantData(event: event); | |||||
if(!EmptyUtil.isEmpty(parentData)){ | |||||
yield HomeQuickEntryLoadedState(model: parentData); | |||||
return; | |||||
} | |||||
/// 获取本地缓存数据 | |||||
var cached = await repository.fetchCachedData(event: event); | var cached = await repository.fetchCachedData(event: event); | ||||
if (!EmptyUtil.isEmpty(cached)) { | if (!EmptyUtil.isEmpty(cached)) { | ||||
yield HomeQuickEntryCachedState(); | |||||
yield HomeQuickEntryCachedState(model: cached); | |||||
} | } | ||||
/// 获取网络的数据 | |||||
var result = await repository.fetchData(event: event); | var result = await repository.fetchData(event: event); | ||||
if (!EmptyUtil.isEmpty(result)) { | if (!EmptyUtil.isEmpty(result)) { | ||||
yield HomeQuickEntryLoadedState(); | |||||
yield HomeQuickEntryLoadedState(model: result); | |||||
} else { | } else { | ||||
yield HomeQuickEntryErrorState(); | yield HomeQuickEntryErrorState(); | ||||
} | } | ||||
@@ -1,27 +1,58 @@ | |||||
import 'dart:convert'; | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/model/home_quick_entry_model.dart'; | |||||
import 'package:zhiying_comm/util/net_util.dart'; | import 'package:zhiying_comm/util/net_util.dart'; | ||||
import 'package:zhiying_comm/util/empty_util.dart'; | import 'package:zhiying_comm/util/empty_util.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'home_quick_entry_event.dart'; | import 'home_quick_entry_event.dart'; | ||||
class HomeQuickEntryRepository { | class HomeQuickEntryRepository { | ||||
/// 获取数据 | /// 获取数据 | ||||
Future<dynamic> fetchData({@required HomeQuickEntryInitEvent event}) async { | |||||
var result = await NetUtil.post('/api/v1/mod', params: {'ids':[event.model['mod_id']]}, cache: true); | |||||
if(NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])){ | |||||
Future<HomeQuickEntryModel> fetchData({@required HomeQuickEntryInitEvent event}) async { | |||||
var result = await NetUtil.post('/api/v1/mod/${event.model['mod_id']}', params: { 'ids': [event.model['mod_id']]}, cache: true, method: NetMethod.GET); | |||||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||||
Map<String, dynamic> data = result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]; | |||||
return _getHomeQuickEntryModel(data); | |||||
} | |||||
return null; | |||||
} | |||||
/// 获取父页面传进来的数据 | |||||
Future<HomeQuickEntryModel> fetchPreantData({@required HomeQuickEntryInitEvent event}) async{ | |||||
try{ | |||||
String jsonStr = event.model['data']; | |||||
return HomeQuickEntryModel.fromJson(json.decode(jsonStr)); | |||||
}catch(e){ | |||||
Logger.log(e); | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
/// 获取缓存数据 | /// 获取缓存数据 | ||||
Future<dynamic> fetchCachedData({@required HomeQuickEntryInitEvent event}) async{ | |||||
var result = await NetUtil.getRequestCachedData('/api/v1/mod', params: {'ids':[event.model['mod_id']]}); | |||||
if(!EmptyUtil.isEmpty(result)){ | |||||
return result; | |||||
Future<HomeQuickEntryModel> fetchCachedData({@required HomeQuickEntryInitEvent event}) async { | |||||
var result = await NetUtil.getRequestCachedData('/api/v1/mod/${event.model['mod_id']}', params: {'ids': [event.model['mod_id']]}); | |||||
if (!EmptyUtil.isEmpty(result)) { | |||||
return _getHomeQuickEntryModel(result); | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
HomeQuickEntryModel _getHomeQuickEntryModel(var data) { | |||||
try { | |||||
if (!EmptyUtil.isEmpty(data) && !EmptyUtil.isEmpty(data['data'])) { | |||||
var jsonData = jsonDecode(data['data']); | |||||
if (!EmptyUtil.isEmpty(jsonData)) { | |||||
HomeQuickEntryModel model = HomeQuickEntryModel.fromJson(jsonData); | |||||
if (null != model) { | |||||
return model; | |||||
} | |||||
} | |||||
} | |||||
} catch (e) { | |||||
Logger.log(e); | |||||
} | |||||
return null; | |||||
} | |||||
} | } |
@@ -1,4 +1,6 @@ | |||||
import 'package:equatable/equatable.dart'; | import 'package:equatable/equatable.dart'; | ||||
import 'package:flutter/cupertino.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/model/home_quick_entry_model.dart'; | |||||
abstract class HomeQuickEntryState extends Equatable { | abstract class HomeQuickEntryState extends Equatable { | ||||
const HomeQuickEntryState(); | const HomeQuickEntryState(); | ||||
@@ -14,10 +16,24 @@ class InitialHomeQuickEntryState extends HomeQuickEntryState { | |||||
} | } | ||||
/// 加载数据完毕 | /// 加载数据完毕 | ||||
class HomeQuickEntryLoadedState extends HomeQuickEntryState {} | |||||
class HomeQuickEntryLoadedState extends HomeQuickEntryState { | |||||
final HomeQuickEntryModel model; | |||||
const HomeQuickEntryLoadedState({@required this.model}); | |||||
@override | |||||
List<Object> get props => [this.model]; | |||||
} | |||||
/// 加载缓存数据 | /// 加载缓存数据 | ||||
class HomeQuickEntryCachedState extends HomeQuickEntryState {} | |||||
class HomeQuickEntryCachedState extends HomeQuickEntryState { | |||||
final HomeQuickEntryModel model; | |||||
const HomeQuickEntryCachedState({@required this.model}); | |||||
@override | |||||
List<Object> get props => [this.model]; | |||||
} | |||||
/// 加载数据出错 | /// 加载数据出错 | ||||
class HomeQuickEntryErrorState extends HomeQuickEntryState {} | class HomeQuickEntryErrorState extends HomeQuickEntryState {} |
@@ -0,0 +1,309 @@ | |||||
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:zhiying_base_widget/widgets/home/home_quick_entry/bloc/bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/bloc/home_quick_entry_repository.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||||
import 'package:cached_network_image/cached_network_image.dart'; | |||||
import 'home_quick_entry_sk.dart'; | |||||
import 'model/home_quick_entry_model.dart'; | |||||
class HomeQuickEntry extends StatelessWidget { | |||||
final Map<String, dynamic> model; | |||||
const HomeQuickEntry(this.model); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocProvider<HomeQuickEntryBloc>( | |||||
create: (_) => HomeQuickEntryBloc(repository: HomeQuickEntryRepository())..add(HomeQuickEntryInitEvent(model: model)), | |||||
child: HomeQuickEntryContianer(), | |||||
); | |||||
} | |||||
} | |||||
class HomeQuickEntryContianer extends StatefulWidget { | |||||
@override | |||||
_HomeQuickEntryContianerState createState() => _HomeQuickEntryContianerState(); | |||||
} | |||||
class _HomeQuickEntryContianerState extends State<HomeQuickEntryContianer> { | |||||
/// Icon点击事件 | |||||
void _itemIconClick(TypeNormal item){ | |||||
print("item type = ${item.skip_identifier}"); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocConsumer<HomeQuickEntryBloc, HomeQuickEntryState>( | |||||
listener: (context, state) { | |||||
Logger.log('数据加载出错'); | |||||
}, | |||||
buildWhen: (prev, current) { | |||||
if (current is HomeQuickEntryErrorState) { | |||||
return false; | |||||
} | |||||
return true; | |||||
}, | |||||
builder: (context, state) { | |||||
if (state is HomeQuickEntryCachedState) { | |||||
return _getMainWidget(state.model); | |||||
} | |||||
if (state is HomeQuickEntryLoadedState) { | |||||
return _getMainWidget(state.model); | |||||
} | |||||
return HomeQuickEntrySkeleton(); | |||||
}, | |||||
); | |||||
} | |||||
Widget _getMainWidget(HomeQuickEntryModel model) { | |||||
// 数据总数 | |||||
int totalDataSize = model?.type_normal?.length ?? 0; | |||||
// 展示的总行数 | |||||
int totalRowSize = int.parse(model?.row_size ?? '1'); | |||||
// 展示的列数 | |||||
int columSize = int.parse(model?.colum_size ?? '5'); | |||||
// 图标的高度 | |||||
double iconHeight = 40.0; | |||||
// 标题的高度 | |||||
double titleHeight = 20.0; | |||||
// 子元素的高度 | |||||
double itemHeight = iconHeight; | |||||
// 如果有一级标题 | |||||
if (!EmptyUtil.isEmpty(model?.title_1_open) && model.title_1_open == '1') { | |||||
itemHeight = iconHeight + titleHeight; | |||||
} | |||||
//如果有二级标题 | |||||
if (!EmptyUtil.isEmpty(model?.title_2_open) && model.title_2_open == '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_open) && model.pagination_open == '0') { | |||||
totalHeight = totalRowSize * (itemHeight + barMargin); | |||||
} | |||||
return Container( | |||||
color: Colors.white, | |||||
child: Container( | |||||
margin: const EdgeInsets.only(top: 15, bottom: 15 ), | |||||
height: totalHeight, // 总体高度 | |||||
width: double.infinity, | |||||
color: Colors.white, | |||||
child: Swiper( | |||||
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: _getSwiperPaginationContorl(model, totalPage), | |||||
), | |||||
), | |||||
); | |||||
} | |||||
/// 页的数据 | |||||
Widget _getPageWidget({double titleHeight, double iconHeight, int totalPage, int currentPage, int columSize, int totalRowSize, int totalDataSize, HomeQuickEntryModel model,double itemHeight}){ | |||||
List rowList = []; | |||||
for(int i = 0 ; i < totalRowSize; i ++){ | |||||
rowList.add(i); | |||||
} | |||||
return Column( | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
mainAxisAlignment: MainAxisAlignment.start, | |||||
children: rowList.map((currentRow){ | |||||
return Container( | |||||
padding: EdgeInsets.only(bottom: 15), | |||||
width: double.infinity, | |||||
child: _getRowWidget(titleHeight: titleHeight, iconHeight: iconHeight, totalPage: totalPage, currentPage: currentPage, columSize: columSize, totalRowSize: totalRowSize, totalDataSize: totalDataSize, model: model, currentRow: currentRow, itemHeight: itemHeight), | |||||
); | |||||
}).toList(), | |||||
); | |||||
} | |||||
/// 行的数据 | |||||
Widget _getRowWidget({double titleHeight, double iconHeight, int totalPage, int currentPage, int columSize, int totalRowSize, int totalDataSize, HomeQuickEntryModel model, int currentRow, double itemHeight}) { | |||||
List itemList = []; | |||||
for(int i = 0; i < columSize; i++){ | |||||
itemList.add(i); | |||||
} | |||||
return Row( | |||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||||
crossAxisAlignment: CrossAxisAlignment.center, | |||||
children: itemList.map((currentIndex){ | |||||
return _getColumWidget(titleHeight: titleHeight, iconHeight: iconHeight, totalPage: totalPage, currentPage: currentPage, totalDataSize: totalDataSize, columSize: columSize, totalRowSize: totalRowSize, model: model, currentRow: currentRow, currentColum: currentIndex, itemHeight: itemHeight,); | |||||
}).toList(), | |||||
); | |||||
} | |||||
/// item 的数据 | |||||
Widget _getColumWidget({double titleHeight, double iconHeight, int totalPage, int currentPage, int columSize, int totalRowSize, int totalDataSize, HomeQuickEntryModel model, int currentRow,int currentColum, double itemHeight}){ | |||||
// 当前index = 当前的页数+1 * 当前的行数 + 当前的列数 | |||||
// int currentIndex = (currentPage + 1) * currentRow + currentColum + currentRow*columSize; | |||||
// int currentIndex = currentPage != 0 ? currentPage * (columSize * totalRowSize) + columSize + currentRow * columSize : | |||||
// currentColum + currentRow * columSize; | |||||
// 当前元素的下表 = 当前的列数 + 当前的行数 * 列数 + 当前的页数 * 当前的行数 + 当前的列数 | |||||
int currentIndex = currentColum + currentRow * columSize + currentPage * totalRowSize * columSize; | |||||
// print('current Index sss = $currentIndex'); | |||||
if(currentIndex >= totalDataSize){ | |||||
return Container( height: itemHeight, width: 60,); | |||||
} | |||||
TypeNormal item = model?.type_normal[currentIndex]; | |||||
return GestureDetector( | |||||
behavior: HitTestBehavior.opaque, | |||||
onTap: ()=> _itemIconClick(item), | |||||
child: Container( | |||||
height: itemHeight, | |||||
width: 60, | |||||
// color: Colors.red, | |||||
child: Column( | |||||
children: <Widget>[ | |||||
/// 图标 | |||||
MyNetWorkImage(item.img), | |||||
/// 一级标题 | |||||
Visibility( | |||||
visible: !EmptyUtil.isEmpty(model?.title_1_open) && model.title_1_open == '1', | |||||
child: Padding( | |||||
padding: const EdgeInsets.only(top: 5), | |||||
child: Text(item?.title_1 ?? '', style: TextStyle( fontSize: 10, color: HexColor.fromHex(model?.title_1_text_color)),), | |||||
), | |||||
), | |||||
/// 二级标题 | |||||
Visibility( | |||||
visible: !EmptyUtil.isEmpty(model?.title_2_open) && model.title_2_open == '1', | |||||
child: Padding( | |||||
padding: const EdgeInsets.only(top: 5), | |||||
child: Text(item?.title_2 ?? '', style: TextStyle( fontSize: 10, color: HexColor.fromHex(model?.title_2_text_color)),), | |||||
), | |||||
) | |||||
], | |||||
), | |||||
), | |||||
); | |||||
} | |||||
/// 进度条 | |||||
SwiperPagination _getSwiperPaginationContorl(HomeQuickEntryModel model, int pageCount){ | |||||
if(EmptyUtil.isEmpty(model?.pagination_open) || model.pagination_open == '0'){ | |||||
return null; | |||||
} | |||||
if(model.pagination == 'type_point'){ | |||||
// 点点点进度条 | |||||
return _swiperPaginationDot(model); | |||||
}else{ | |||||
// 自定义进度条 | |||||
return _swiperCustomPagination(pageCount); | |||||
} | |||||
} | |||||
// 进度条 圆形 | |||||
SwiperPagination _swiperPaginationDot(HomeQuickEntryModel model){ | |||||
return SwiperPagination(margin: const EdgeInsets.only(), builder: DotSwiperPaginationBuilder( color: HexColor.fromHex(model?.pagination_unselect_color), activeColor: HexColor.fromHex(model?.pagination_select_color), size: 8, activeSize: 8)); | |||||
} | |||||
// 自定义进度条 条形 | |||||
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, 1), | |||||
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(), | |||||
), | |||||
); | |||||
}); | |||||
} | |||||
} | |||||
/// | |||||
/// 图片build 优化 | |||||
/// | |||||
class MyNetWorkImage extends StatelessWidget { | |||||
final String imgUrl; | |||||
final double width; | |||||
const MyNetWorkImage(this.imgUrl, {this.width = 40}); | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return RepaintBoundary( | |||||
child: CachedNetworkImage( | |||||
width: width, | |||||
imageUrl: imgUrl, | |||||
), | |||||
); | |||||
} | |||||
} |
@@ -1,5 +1,6 @@ | |||||
import 'package:flutter/src/widgets/framework.dart'; | import 'package:flutter/src/widgets/framework.dart'; | ||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'home_quick_entry.dart'; | |||||
import 'home_quick_entry_sk.dart'; | import 'home_quick_entry_sk.dart'; | ||||
import 'home_quick_entry_widget.dart'; | import 'home_quick_entry_widget.dart'; | ||||
@@ -14,6 +15,6 @@ class HomeQuickEntryCreater extends WidgetCreater { | |||||
@override | @override | ||||
List<Widget> createWidgets(Map<String, dynamic> model) { | List<Widget> createWidgets(Map<String, dynamic> model) { | ||||
return [HomeQuickEntryWidget(model)]; | |||||
return [HomeQuickEntry(model)]; | |||||
} | } | ||||
} | } |
@@ -1,67 +1,118 @@ | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||
import 'package:flutter_swiper/flutter_swiper.dart'; | import 'package:flutter_swiper/flutter_swiper.dart'; | ||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/bloc/bloc.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/bloc/home_quick_entry_repository.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/home_quick_entry_sk.dart'; | |||||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/model/home_quick_entry_model.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:flutter_bloc/flutter_bloc.dart'; | |||||
/// | /// | ||||
/// 首页的快速入口widget | /// 首页的快速入口widget | ||||
/// | /// | ||||
class HomeQuickEntryWidget extends StatelessWidget { | class HomeQuickEntryWidget extends StatelessWidget { | ||||
final Map<String, dynamic> model; | final Map<String, dynamic> model; | ||||
HomeQuickEntryWidget(this.model); | HomeQuickEntryWidget(this.model); | ||||
var data = []; | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
return BlocProvider<HomeQuickEntryBloc>( | |||||
create: (_) => HomeQuickEntryBloc(repository: HomeQuickEntryRepository())..add(HomeQuickEntryInitEvent(model: model)), | |||||
child: HomeQuickEntryWidgetContianer(), | |||||
); | |||||
} | |||||
} | |||||
class HomeQuickEntryWidgetContianer extends StatefulWidget { | |||||
@override | |||||
_HomeQuickEntryWidgetContianerState createState() => _HomeQuickEntryWidgetContianerState(); | |||||
} | |||||
class _HomeQuickEntryWidgetContianerState extends State<HomeQuickEntryWidgetContianer> { | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
int dataSize = 26; // 总数 | |||||
int columSize = 5; // 列数 | |||||
int rowSize = 2; // 行数 | |||||
return BlocConsumer<HomeQuickEntryBloc, HomeQuickEntryState>( | |||||
listener: (context, state) { | |||||
Logger.log('数据加载出错'); | |||||
}, | |||||
buildWhen: (prev, current) { | |||||
if (current is HomeQuickEntryErrorState) { | |||||
return false; | |||||
} | |||||
return true; | |||||
}, | |||||
builder: (context, state) { | |||||
if (state is HomeQuickEntryCachedState) { | |||||
return _getMainWidget(state.model); | |||||
} | |||||
if (state is HomeQuickEntryLoadedState) { | |||||
return _getMainWidget(state.model); | |||||
} | |||||
return HomeQuickEntrySkeleton(); | |||||
}, | |||||
); | |||||
} | |||||
for(int i = 0; i < dataSize; i ++ ){ | |||||
data.add('$i'); | |||||
} | |||||
// 页数 | |||||
int pageCount = data.length % (rowSize * columSize) == 0 | |||||
? data.length ~/ (rowSize * columSize) | |||||
: (data.length ~/ (rowSize * columSize)) + 1; | |||||
Widget _getMainWidget(HomeQuickEntryModel model) { | |||||
int dataSize = 15;//model?.type_normal?.length ?? 0; // 总数 | |||||
int columSize = 5;//int.parse(model?.colum_size ?? '5'); // 列数 | |||||
int rowSize = 2;//int.parse(model?.row_size ?? '2'); // 行数 | |||||
rowSize = columSize * rowSize <= dataSize ? rowSize : dataSize % columSize == 0 ? dataSize ~/ columSize : (dataSize ~/ columSize) +1; | |||||
// 页数 总数 % (columSize * rowSize) | |||||
int pageCount = dataSize % (rowSize * columSize) == 0 ? dataSize ~/ (rowSize * columSize) : (dataSize ~/ (rowSize * columSize)) + 1; | |||||
// 进度条底部距离 | |||||
const double bottomSize = 15.0; | |||||
// 子元素之间的下边距 | |||||
const double itemPadding = 15.0; | |||||
// 图片的高度 | |||||
const double iconHeight = 40.0; | |||||
// 一个标题➕边距的高度 | |||||
const double titleHeight = 20; | |||||
// 总体的高度 == 行数 * (图片高度 + 标题高度 + 元素之间的边距) + 上下内边距 | |||||
double containerHeight = rowSize * (iconHeight + titleHeight + itemPadding*2) + (bottomSize*2); | |||||
double containerHeight = 145.h * ( data.length >= rowSize * columSize ? rowSize : (data.length / columSize).ceil()) + (rowSize == 1 ? 0 : 25.h); | |||||
// double headHeight = 50.h ; | |||||
return Container( | return Container( | ||||
margin: EdgeInsets.only(bottom: 25.h), | |||||
height: containerHeight ,//+ headHeight, | |||||
// padding: const EdgeInsets.only(bottom: bottomSize, top: bottomSize), | |||||
// padding: const EdgeInsets.only(top: bottomSize), | |||||
color: Colors.green, | |||||
height: containerHeight, | |||||
width: double.infinity, | width: double.infinity, | ||||
child: Column( | child: Column( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
// Container( | |||||
// margin: EdgeInsets.symmetric(horizontal: 25.w), | |||||
// height: headHeight, | |||||
// color: Colors.green, | |||||
// ), | |||||
Expanded( | Expanded( | ||||
child: Swiper( | |||||
itemHeight: 145.h, | |||||
containerHeight: double.infinity, | |||||
duration: 100, | |||||
scrollDirection: Axis.horizontal, | |||||
loop: false, | |||||
index: 0, | |||||
autoplay: false, | |||||
itemCount: pageCount, // 页数 | |||||
itemBuilder: (BuildContext context, int index) { | |||||
return HomeQuickEntrySwiperItem( | |||||
data: data, | |||||
showDataSize: columSize * rowSize, | |||||
page: index, | |||||
columSize: columSize, | |||||
rowSize: rowSize, | |||||
); | |||||
}, | |||||
pagination: _SwiperCustomPagination(pageCount), | |||||
child: Container( | |||||
// color: Colors.yellowAccent, | |||||
child: Swiper( | |||||
itemHeight: double.infinity, | |||||
itemWidth: double.infinity, | |||||
duration: 100, | |||||
scrollDirection: Axis.horizontal, | |||||
loop: false, | |||||
containerWidth: double.infinity, | |||||
containerHeight: 250, | |||||
index: 0, | |||||
itemCount: pageCount, | |||||
// 页数 | |||||
itemBuilder: (BuildContext context, int index) { | |||||
return HomeQuickEntrySwiperItem( | |||||
data: model?.type_normal, | |||||
dataSize: dataSize, | |||||
showDataSize: columSize * rowSize, | |||||
page: index, | |||||
columSize: columSize, | |||||
rowSize: rowSize, | |||||
itemPadding: itemPadding, | |||||
); | |||||
}, | |||||
pagination: _SwiperCustomPagination(pageCount), | |||||
), | |||||
), | ), | ||||
) | ) | ||||
], | ], | ||||
@@ -70,51 +121,40 @@ class HomeQuickEntryWidget extends StatelessWidget { | |||||
} | } | ||||
// 自定义进度条 | // 自定义进度条 | ||||
SwiperPlugin _SwiperCustomPagination(int pageCount){ | |||||
SwiperPlugin _SwiperCustomPagination(int pageCount) { | |||||
List list = []; | List list = []; | ||||
for(int i = 0; i < pageCount; i ++){ | |||||
for (int i = 0; i < pageCount; i++) { | |||||
list.add(i); | list.add(i); | ||||
} | } | ||||
return SwiperCustomPagination( | |||||
builder: (BuildContext context, SwiperPluginConfig config){ | |||||
return Align( | |||||
alignment: Alignment(0.0, 1), | |||||
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(), | |||||
), | |||||
); | |||||
} | |||||
); | |||||
return SwiperCustomPagination(builder: (BuildContext context, SwiperPluginConfig config) { | |||||
return Align( | |||||
alignment: Alignment(0.0, 1), | |||||
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(), | |||||
), | |||||
); | |||||
}); | |||||
} | } | ||||
} | } | ||||
@@ -127,39 +167,46 @@ class HomeQuickEntrySwiperItem extends StatelessWidget { | |||||
final int showDataSize; // 显示的数据 | final int showDataSize; // 显示的数据 | ||||
final int columSize; // 列数 | final int columSize; // 列数 | ||||
final int rowSize; // 行数 | final int rowSize; // 行数 | ||||
final int dataSize; | |||||
final double itemPadding; | |||||
const HomeQuickEntrySwiperItem( | |||||
{this.page, | |||||
this.data, | |||||
this.showDataSize, | |||||
this.columSize, | |||||
this.rowSize}); | |||||
const HomeQuickEntrySwiperItem({this.page, this.data, this.showDataSize, this.columSize, this.rowSize, this.itemPadding, this.dataSize}); | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
// 当前显示的个数 | // 当前显示的个数 | ||||
int itemCount = (data.length - page * showDataSize) >= showDataSize ? showDataSize : (data.length - page * showDataSize); | |||||
return GridView.builder( | |||||
cacheExtent: double.infinity, | |||||
scrollDirection: Axis.vertical, | |||||
shrinkWrap: true, | |||||
padding: const EdgeInsets.all(0), | |||||
reverse: false, | |||||
physics: NeverScrollableScrollPhysics(), | |||||
itemCount: itemCount, | |||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( | |||||
crossAxisCount: columSize, | |||||
childAspectRatio: 1, | |||||
crossAxisSpacing: 0, | |||||
mainAxisSpacing: 25.h, | |||||
), | |||||
itemBuilder: (context, i) { | |||||
return HomeQuickEntryItem( | |||||
data: data[ itemCount == showDataSize ? page * showDataSize + i : page == 0 ? page + i : page * showDataSize + i ] | |||||
); | |||||
}); | |||||
// int itemCount = (data.length - page * showDataSize) >= showDataSize ? showDataSize : (data.length - page * showDataSize); | |||||
int itemCount = (dataSize - page * showDataSize) >= showDataSize ? showDataSize : (dataSize - page * showDataSize); | |||||
print('${itemCount}'); | |||||
return Container( | |||||
// color: Colors.cyan, | |||||
height: double.infinity, | |||||
width: double.infinity, | |||||
// margin: const EdgeInsets.only(bottom: 15), | |||||
child: GridView.builder( | |||||
cacheExtent: double.infinity, | |||||
scrollDirection: Axis.vertical, | |||||
shrinkWrap: true, | |||||
primary: false, | |||||
padding: const EdgeInsets.only(top: 15), | |||||
reverse: false, | |||||
addAutomaticKeepAlives: false, | |||||
addRepaintBoundaries: false, | |||||
physics: NeverScrollableScrollPhysics(), | |||||
itemCount: itemCount, | |||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( | |||||
crossAxisCount: columSize, | |||||
childAspectRatio: 1, | |||||
crossAxisSpacing: 0, | |||||
mainAxisSpacing: 0, | |||||
), | |||||
itemBuilder: (context, i) { | |||||
// return HomeQuickEntryItem(data: data[itemCount == showDataSize ? page * showDataSize + i : page == 0 ? page + i : page * showDataSize + i], itemPaddding: itemPadding,); | |||||
// 最后一行 | |||||
bool isLast = i >= (rowSize -1) * columSize; | |||||
return HomeQuickEntryItem(data: null, itemPaddding: itemPadding, isLastRow: isLast,); | |||||
}), | |||||
); | |||||
} | } | ||||
} | } | ||||
@@ -167,37 +214,49 @@ class HomeQuickEntrySwiperItem extends StatelessWidget { | |||||
/// 快速入口的样式 | /// 快速入口的样式 | ||||
/// | /// | ||||
class HomeQuickEntryItem extends StatelessWidget { | class HomeQuickEntryItem extends StatelessWidget { | ||||
var data; | |||||
final TypeNormal data; | |||||
final double itemPaddding; | |||||
final bool isLastRow; | |||||
HomeQuickEntryItem({this.data}); | |||||
HomeQuickEntryItem({this.data, this.itemPaddding, this.isLastRow}); | |||||
/// 子图标的点击 | /// 子图标的点击 | ||||
_itemOnClick(context){ | |||||
Navigator.push(context, MaterialPageRoute( | |||||
builder: (context){ | |||||
return PageFactory.create('login', null); | |||||
} | |||||
)); | |||||
_itemOnClick(context) { | |||||
Navigator.push(context, MaterialPageRoute(builder: (context) { | |||||
return PageFactory.create('login', null); | |||||
})); | |||||
} | } | ||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return GestureDetector( | return GestureDetector( | ||||
onTap: () => _itemOnClick(context), | onTap: () => _itemOnClick(context), | ||||
child: Column( | |||||
crossAxisAlignment: CrossAxisAlignment.center, | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
children: <Widget>[ | |||||
// 图片 | |||||
MyNetWorkImage(), | |||||
SizedBox(height: 10.h), | |||||
Text( | |||||
'京东爆款$data', | |||||
style: | |||||
TextStyle(color: HexColor.fromHex('#666666'), fontSize: 20.sp), | |||||
), | |||||
child: Container( | |||||
margin: EdgeInsets.only(bottom: isLastRow ? 0 :0), | |||||
color: Colors.red, | |||||
child: Column( | |||||
crossAxisAlignment: CrossAxisAlignment.center, | |||||
mainAxisAlignment: MainAxisAlignment.start, | |||||
children: <Widget>[ | |||||
// 图片 | |||||
MyNetWorkImage(data?.img?? 'https://profile.csdnimg.cn/3/3/0/3_canhuashu'), | |||||
Padding( | |||||
padding: const EdgeInsets.only(top: 5), | |||||
child: Text( | |||||
data?.title_1 ?? '京东', | |||||
style: TextStyle(color: HexColor.fromHex('#666666'), fontSize: 20.sp), | |||||
)), | |||||
Padding( | |||||
padding: const EdgeInsets.only(top: 5), | |||||
child: Text( | |||||
data?.title_1 ?? '京东', | |||||
style: TextStyle(color: HexColor.fromHex('#666666'), fontSize: 20.sp), | |||||
)), | |||||
// SizedBox(height: 25.h,) | // SizedBox(height: 25.h,) | ||||
], | |||||
], | |||||
), | |||||
), | ), | ||||
); | ); | ||||
} | } | ||||
@@ -207,13 +266,16 @@ class HomeQuickEntryItem extends StatelessWidget { | |||||
/// 图片build 优化 | /// 图片build 优化 | ||||
/// | /// | ||||
class MyNetWorkImage extends StatelessWidget { | class MyNetWorkImage extends StatelessWidget { | ||||
final String imgUrl; | |||||
const MyNetWorkImage(this.imgUrl); | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return RepaintBoundary( | return RepaintBoundary( | ||||
child: CachedNetworkImage( | child: CachedNetworkImage( | ||||
height: 80.h, | |||||
width: 80.h, | |||||
imageUrl: 'https://upload.jianshu.io/users/upload_avatars/665534/aff6ec240f60?imageMogr2/auto-orient/strip|imageView2/1/w/96/h/96/format/webp', | |||||
width: 40, | |||||
imageUrl: imgUrl, | |||||
), | ), | ||||
); | ); | ||||
} | } | ||||
@@ -0,0 +1,98 @@ | |||||
class HomeQuickEntryDataModel { | |||||
String data; | |||||
String aspect_ratio; | |||||
String badge; | |||||
String bg_color; | |||||
String bg_color_t; | |||||
String bg_img; | |||||
String font_color; | |||||
String icon; | |||||
String img; | |||||
int is_global; | |||||
String margin; | |||||
int mod_id; | |||||
String mod_name; | |||||
int mod_pid; | |||||
String path; | |||||
String position; | |||||
String skip_identifier; | |||||
int sort; | |||||
String subtitle; | |||||
String title; | |||||
String url; | |||||
HomeQuickEntryDataModel( | |||||
{this.data, | |||||
this.aspect_ratio, | |||||
this.badge, | |||||
this.bg_color, | |||||
this.bg_color_t, | |||||
this.bg_img, | |||||
this.font_color, | |||||
this.icon, | |||||
this.img, | |||||
this.is_global, | |||||
this.margin, | |||||
this.mod_id, | |||||
this.mod_name, | |||||
this.mod_pid, | |||||
this.path, | |||||
this.position, | |||||
this.skip_identifier, | |||||
this.sort, | |||||
this.subtitle, | |||||
this.title, | |||||
this.url}); | |||||
factory HomeQuickEntryDataModel.fromJson(Map<String, dynamic> json) { | |||||
return HomeQuickEntryDataModel( | |||||
data: json['data'], | |||||
aspect_ratio: json['aspect_ratio'], | |||||
badge: json['badge'], | |||||
bg_color: json['bg_color'], | |||||
bg_color_t: json['bg_color_t'], | |||||
bg_img: json['bg_img'], | |||||
font_color: json['font_color'], | |||||
icon: json['icon'], | |||||
img: json['img'], | |||||
is_global: json['is_global'], | |||||
margin: json['margin'], | |||||
mod_id: json['mod_id'], | |||||
mod_name: json['mod_name'], | |||||
mod_pid: json['mod_pid'], | |||||
path: json['path'], | |||||
position: json['position'], | |||||
skip_identifier: json['skip_identifier'], | |||||
sort: json['sort'], | |||||
subtitle: json['subtitle'], | |||||
title: json['title'], | |||||
url: json['url'], | |||||
); | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['data'] = this.data; | |||||
data['aspect_ratio'] = this.aspect_ratio; | |||||
data['badge'] = this.badge; | |||||
data['bg_color'] = this.bg_color; | |||||
data['bg_color_t'] = this.bg_color_t; | |||||
data['bg_img'] = this.bg_img; | |||||
data['font_color'] = this.font_color; | |||||
data['icon'] = this.icon; | |||||
data['img'] = this.img; | |||||
data['is_global'] = this.is_global; | |||||
data['margin'] = this.margin; | |||||
data['mod_id'] = this.mod_id; | |||||
data['mod_name'] = this.mod_name; | |||||
data['mod_pid'] = this.mod_pid; | |||||
data['path'] = this.path; | |||||
data['position'] = this.position; | |||||
data['skip_identifier'] = this.skip_identifier; | |||||
data['sort'] = this.sort; | |||||
data['subtitle'] = this.subtitle; | |||||
data['title'] = this.title; | |||||
data['url'] = this.url; | |||||
return data; | |||||
} | |||||
} |
@@ -1,4 +1,100 @@ | |||||
class HomeQuickEntryModel { | |||||
String colum_size; | |||||
String data_type; | |||||
String pagination; | |||||
String pagination_select_color; | |||||
String pagination_unselect_color; | |||||
String row_size; | |||||
String title_1_text_color; | |||||
String title_2_text_color; | |||||
List<TypeNormal> type_normal; | |||||
String title_1_open; | |||||
String title_2_open; | |||||
String pagination_open; | |||||
class HomeQuickEntryModel{ | |||||
HomeQuickEntryModel( | |||||
{this.colum_size, | |||||
this.data_type, | |||||
this.pagination, | |||||
this.pagination_select_color, | |||||
this.pagination_unselect_color, | |||||
this.row_size, | |||||
this.title_1_text_color, | |||||
this.title_2_text_color, | |||||
this.title_1_open, | |||||
this.title_2_open, | |||||
this.pagination_open, | |||||
this.type_normal}); | |||||
} | |||||
factory HomeQuickEntryModel.fromJson(Map<String, dynamic> json) { | |||||
return HomeQuickEntryModel( | |||||
colum_size: json['colum_size']?.toString(), | |||||
data_type: json['data_type']?.toString(), | |||||
pagination: json['pagination']?.toString(), | |||||
pagination_select_color: json['pagination_select_color']?.toString(), | |||||
pagination_unselect_color: json['pagination_unselect_color']?.toString(), | |||||
row_size: json['row_size']?.toString(), | |||||
title_1_text_color: json['title_1_text_color']?.toString(), | |||||
title_2_text_color: json['title_2_text_color']?.toString(), | |||||
title_1_open: json['title_1_open']?.toString(), | |||||
title_2_open: json['title_2_open']?.toString(), | |||||
pagination_open: json['pagination_open']?.toString(), | |||||
type_normal: json['type_normal'] != null ? (json['type_normal'] as List).map((i) => TypeNormal.fromJson(i)).toList() : null, | |||||
); | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['colum_size'] = this.colum_size; | |||||
data['data_type'] = this.data_type; | |||||
data['pagination'] = this.pagination; | |||||
data['pagination_select_color'] = this.pagination_select_color; | |||||
data['pagination_unselect_color'] = this.pagination_unselect_color; | |||||
data['row_size'] = this.row_size; | |||||
data['title_1_text_color'] = this.title_1_text_color; | |||||
data['title_2_text_color'] = this.title_2_text_color; | |||||
data['pagination_open'] = this.pagination_open; | |||||
data['title_1_open'] = this.title_1_open; | |||||
data['title_2_open'] = this.title_2_open; | |||||
if (this.type_normal != null) { | |||||
data['type_normal'] = this.type_normal.map((v) => v.toJson()).toList(); | |||||
} | |||||
return data; | |||||
} | |||||
} | |||||
class TypeNormal { | |||||
String img; | |||||
String required_login; | |||||
String required_taobao_auth; | |||||
String skip_identifier; | |||||
String title_1; | |||||
String title_2; | |||||
String type; | |||||
TypeNormal({this.img, this.required_login, this.required_taobao_auth, this.skip_identifier, this.title_1, this.title_2, this.type}); | |||||
factory TypeNormal.fromJson(Map<String, dynamic> json) { | |||||
return TypeNormal( | |||||
img: json['img']?.toString(), | |||||
required_login: json['required_login']?.toString(), | |||||
required_taobao_auth: json['required_taobao_auth']?.toString(), | |||||
skip_identifier: json['skip_identifier']?.toString(), | |||||
title_1: json['title_1']?.toString(), | |||||
title_2: json['title_2']?.toString(), | |||||
type: json['type']?.toString(), | |||||
); | |||||
} | |||||
Map<String, dynamic> toJson() { | |||||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||||
data['img'] = this.img; | |||||
data['required_login'] = this.required_login; | |||||
data['required_taobao_auth'] = this.required_taobao_auth; | |||||
data['skip_identifier'] = this.skip_identifier; | |||||
data['title_1'] = this.title_1; | |||||
data['title_2'] = this.title_2; | |||||
data['type'] = this.type; | |||||
return data; | |||||
} | |||||
} |
@@ -19,6 +19,9 @@ class HomeSlideBannerRepository { | |||||
return null; | return null; | ||||
} | } | ||||
/// 获取父页面传进来的数据 | |||||
/// 获取数据 | /// 获取数据 | ||||
Future<List<HomeSlideBannerModelItems>> fetchData({@required int id}) async { | Future<List<HomeSlideBannerModelItems>> fetchData({@required int id}) async { | ||||
var params = await NetUtil.post('/api/v1/mod', | var params = await NetUtil.post('/api/v1/mod', | ||||