Browse Source

1.对接最新的引导页接口

2.修复商品详情未登录点击底部收藏按钮没响应的问题
tags/0.0.4+8
“yanghuaxuan” 3 years ago
parent
commit
1d8a529569
5 changed files with 302 additions and 84 deletions
  1. +68
    -2
      lib/models/app_config_model.dart
  2. +90
    -11
      lib/pages/goods_details_page/goods_details_page.dart
  3. +107
    -40
      lib/pages/guide_page/guide_page.dart
  4. +13
    -5
      lib/pages/launch_page/launch_page.dart
  5. +24
    -26
      lib/widgets/goods_details/footer/goods_details_footer_widget.dart

+ 68
- 2
lib/models/app_config_model.dart View File

@@ -12,6 +12,9 @@ class AppConfigModel {
// 引导页
AppConfigGuideModel guideImage;

///新引导页参数
GuideData guideData;

static AppConfigModel _config;

AppConfigModel({this.keys, this.guideImage});
@@ -20,13 +23,12 @@ class AppConfigModel {

static Future<AppConfigModel> init({bool isGetCache = false}) async {
try {
String cacheData = await SharedPreferencesUtil.getStringValue(GlobalConfig.GUIDE, defaultVal: '1');
if (isGetCache && cacheData != '1') {
_config = AppConfigModel.fromJson(Map<String, dynamic>.from(json.decode(cacheData)));
Logger.debug('基础设置初始化');
NetUtil.request('/api/v1/app/guide', onSuccess: (data) {
print(data);
Logger.log(json.encode(data));
var cacheString = json.encode(data);
SharedPreferencesUtil.setNetCacheResult(GlobalConfig.GUIDE, cacheString);
});
@@ -49,6 +51,7 @@ class AppConfigModel {
AppConfigModel.fromJson(Map<String, dynamic> json) {
keys = json['keys'] != null ? new AppConfigKeyModel.fromJson(json['keys']) : null;
guideImage = json['guide_image'] != null ? new AppConfigGuideModel.fromJson(json['guide_image']) : null;
guideData = json['guide_data'] != null ? GuideData.fromJson(json['guide_data']) : null;
}

Map<String, dynamic> toJson() {
@@ -101,6 +104,69 @@ class AppConfigKeyModel {
}
}

class GuideData {
String indicatorType;
String indicatorCssType;
String indicatorChooseColor;
String indicatorUnchooseColor;
String btnText;
String btnBgColor;
String btnTextColor;
List<GuideCss> guideCss;

GuideData({this.indicatorType, this.indicatorCssType, this.indicatorChooseColor, this.indicatorUnchooseColor, this.btnText, this.btnBgColor, this.btnTextColor, this.guideCss});

GuideData.fromJson(Map<String, dynamic> json) {
indicatorType = json['indicator_type'];
indicatorCssType = json['indicator_css_type'];
indicatorChooseColor = json['indicator_choose_color'];
indicatorUnchooseColor = json['indicator_unchoose_color'];
btnText = json['btn_text'];
btnBgColor = json['btn_bg_color'];
btnTextColor = json['btn_text_color'];
if (json['guide_css'] != null) {
guideCss = new List<GuideCss>();
json['guide_css'].forEach((v) {
guideCss.add(new GuideCss.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['indicator_type'] = this.indicatorType;
data['indicator_css_type'] = this.indicatorCssType;
data['indicator_choose_color'] = this.indicatorChooseColor;
data['indicator_unchoose_color'] = this.indicatorUnchooseColor;
data['btn_text'] = this.btnText;
data['btn_bg_color'] = this.btnBgColor;
data['btn_text_color'] = this.btnTextColor;
if (this.guideCss != null) {
data['guide_css'] = this.guideCss.map((v) => v.toJson()).toList();
}
return data;
}
}

class GuideCss {
String bgImage;
String contentImage;

GuideCss({this.bgImage, this.contentImage});

GuideCss.fromJson(Map<String, dynamic> json) {
bgImage = json['bg_image'];
contentImage = json['content_image'];
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['bg_image'] = this.bgImage;
data['content_image'] = this.contentImage;
return data;
}
}

class AppConfigKeyItemModel {
String appId;
String appkey;


+ 90
- 11
lib/pages/goods_details_page/goods_details_page.dart View File

@@ -1,3 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:ui';

import 'package:event_bus/event_bus.dart';
@@ -13,6 +15,7 @@ import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart';
import 'package:zhiying_base_widget/widgets/goods_details/appbar/goods_details_appbar_widget.dart';
import 'package:zhiying_base_widget/widgets/goods_details/footer/goods_details_footer_widget.dart';
import 'package:zhiying_base_widget/widgets/goods_details/footer/model/goods_details_footer_model.dart';
import 'package:zhiying_comm/zhiying_comm.dart';

import 'notifier/goods_details_appbar_color_notifier.dart';
@@ -151,17 +154,27 @@ class _GoodsDetailsContainerState extends State<GoodsDetailsContainer> {
Widget _getMainWidget(List<Map<String, dynamic>> datas) {
return Scaffold(
backgroundColor: Colors.white,
body: Container(
color: Color(0xfff1f1f1),
child: Stack(
children: <Widget>[
CustomScrollView(
controller: _controller,
slivers: _createContent(context, datas ?? []),
),
Align(alignment: Alignment.topCenter, child: GoodsDetailsAppBarWidget(datas[0])),
],
)),
body: Stack(
children: <Widget>[
Container(
color: Color(0xfff1f1f1),
child: Stack(
children: <Widget>[
CustomScrollView(
controller: _controller,
slivers: _createContent(context, datas ?? []),
),
Align(alignment: Alignment.topCenter, child: GoodsDetailsAppBarWidget(datas[0])),
],
)),
Align(
alignment: Alignment.bottomCenter,
child: _FloatView(
!EmptyUtil.isEmpty(datas) ? datas[datas.length - 1] : null,
),
)
],
),

/// 底部
bottomNavigationBar: GoodsDetailsFooterWidget(
@@ -261,4 +274,70 @@ class _GoodsDetailsContainerState extends State<GoodsDetailsContainer> {
// ),
);
}

///构建浮动页
_FloatView(Map<String, dynamic> model) {
if (model != null) {
return FloatView(
model: model,
);
}
}
}

class FloatView extends StatefulWidget {
final Map<String, dynamic> model;

const FloatView({Key key, this.model}) : super(key: key);

@override
_FloatViewState createState() => _FloatViewState();
}

class _FloatViewState extends State<FloatView> with TickerProviderStateMixin {
double floatMarginBottom = 0.0;
Timer floatTimer;

AnimationController animationController;


Animation<double> tween;

GoodsDetailsFooterModel footerModel;

@override
void initState() {
footerModel = GoodsDetailsFooterModel.fromJson(json.decode(widget?.model['data']));
animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 3000));
CurvedAnimation curvedAnimation = CurvedAnimation(parent: animationController, curve: Curves.easeInOutBack);
tween = Tween<double>(begin: 5, end: 20).animate(curvedAnimation);
curvedAnimation.addListener(() {
setState(() {});
});

// animationController.repeat(reverse: true);

super.initState();
}

@override
void dispose() {
animationController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Container();
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: tween?.value ?? 0, right: 25),
color: Colors.red,
child: Text(""),
),
],
);
}
}

+ 107
- 40
lib/pages/guide_page/guide_page.dart View File

@@ -7,10 +7,11 @@ import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network
import 'package:zhiying_comm/zhiying_comm.dart';

class GuidePage extends StatefulWidget {
final AppConfigGuideModel model;
final GuideData model;
final List<Uint8List> imageDatas;
final List<Uint8List> bgImageDatas;

const GuidePage(this.model, this.imageDatas, {Key key}) : super(key: key);
const GuidePage(this.model, this.imageDatas, this.bgImageDatas, {Key key}) : super(key: key);

@override
State<StatefulWidget> createState() => _GuidePageState();
@@ -19,54 +20,120 @@ class GuidePage extends StatefulWidget {
class _GuidePageState extends State<GuidePage> {
@override
Widget build(BuildContext context) {
bool isShowIndicator = (widget.model?.isShowIndicator ?? '0') == '1';
bool isShowIndicator = (widget.model?.indicatorType ?? '0') == '1';
List<int> list = List.generate(widget.imageDatas?.length, (index) => index);
return WillPopScope(
onWillPop: () async => false,// 拦截Android返回键
onWillPop: () async => false, // 拦截Android返回键
child: Material(
child: Swiper(
itemBuilder: (BuildContext context, int index) {
// return CachedNetworkImage(imageUrl: widget.model.images[index],fit: BoxFit.cover,);
return Image.memory(widget.imageDatas[index], fit: BoxFit.cover,);
},

loop: false,
itemCount: widget.imageDatas?.length ?? 0,
pagination: isShowIndicator ? 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));
}
Uint8List bgImage;
if (widget.bgImageDatas.length > index) {
bgImage = widget?.bgImageDatas[index];
}

return SafeArea(
child: Container(
margin: EdgeInsets.only(bottom: 40),
height: 4,
width: 25,
decoration: BoxDecoration(borderRadius: borderRadius, color: index == config.activeIndex ? HexColor.fromHex('#FF4242') : HexColor.fromHex('#FFFFFF')),
),
);
}).toList() ,
),
return Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: Image.memory(
bgImage,
).image,
fit: BoxFit.fill)),
child: Center(
child: Image.memory(
widget.imageDatas[index],
fit: BoxFit.fitWidth,
))),
index == widget?.bgImageDatas?.length - 1
? Positioned(
left: 0,
right: 0,
bottom: 110,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
alignment: Alignment.center,
height: 46,
width: 180,
decoration: BoxDecoration(
color: HexColor.fromHex(widget?.model?.btnBgColor ?? ""),
borderRadius: BorderRadius.circular(45),
boxShadow: [BoxShadow(color: HexColor.fromHex(widget?.model?.btnBgColor), offset: Offset(1, 2), blurRadius: 6)]),
child: Text(
widget?.model?.btnText ?? "",
style: TextStyle(color: HexColor.fromHex(widget?.model?.btnTextColor ?? ""), fontSize: 16, height: 1.1),
),
),
],
),
),
)
: Container()
],
);
}) : null,
onIndexChanged: (index) {
},
loop: false,
itemCount: widget.imageDatas?.length ?? 0,
pagination: widget?.model?.indicatorType != "1"
? null
: widget?.model?.indicatorCssType == "2"
? 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) {
return SafeArea(
child: Container(
margin: EdgeInsets.only(bottom: 40, left: 5, right: 5),
height: 4,
width: 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: index == config.activeIndex
? HexColor.fromHex(widget?.model?.indicatorChooseColor)
: HexColor.fromHex(widget?.model?.indicatorUnchooseColor)),
),
);
}).toList(),
),
);
})
: 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) {
return SafeArea(
child: Container(
margin: EdgeInsets.only(bottom: 40, left: 5, right: 5),
height: 10,
width: 10,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: index == config.activeIndex
? HexColor.fromHex(widget?.model?.indicatorChooseColor)
: HexColor.fromHex(widget?.model?.indicatorUnchooseColor)),
),
);
}).toList(),
),
);
}),
onIndexChanged: (index) {},
onTap: (index) {
if (index == widget.model.images.length - 1) {
if (index == widget.model.guideCss.length - 1) {
Navigator.pop(context, true);
}
},


+ 13
- 5
lib/pages/launch_page/launch_page.dart View File

@@ -127,20 +127,28 @@ class _LaunchPageState extends State<LaunchPage> with TickerProviderStateMixin {
Future _showGuideImage() async {
try {
// 引导页
AppConfigGuideModel guide = AppConfigModel.getConfig()?.guideImage;
if (guide != null && guide.images.length > 0) {
AppConfigModel guide = AppConfigModel.getConfig();
if (guide != null && guide.guideData.guideCss.length > 0) {
Dio dio = Dio();
print("加载图片");
List<Uint8List> guideImages = List();
for (int i = 0; i < guide.images.length; i++) {
Response response = await dio.get(guide.images[i], options: Options(responseType: ResponseType.bytes));
List<Uint8List>bgImages = List();
for (int i = 0; i < guide.guideData.guideCss.length; i++) {
Response response = await dio.get(guide.guideData.guideCss[i].contentImage, options: Options(responseType: ResponseType.bytes));
if (response.statusCode == 200) {
Uint8List data = Uint8List.fromList(response.data);
guideImages.add(data);
}
response = await dio.get(guide.guideData.guideCss[i].bgImage, options: Options(responseType: ResponseType.bytes));
if (response.statusCode == 200) {
Uint8List data = Uint8List.fromList(response.data);
bgImages.add(data);
}
}


NativeUtil.notifyInitSuccess();
await Navigator.of(context).push(CupertinoPageRoute(builder: (context) => GuidePage(guide, guideImages)));
await Navigator.of(context).push(CupertinoPageRoute(builder: (context) => GuidePage(guide.guideData, guideImages,bgImages)));
}
} catch (e) {
throw "引导图加载失败";


+ 24
- 26
lib/widgets/goods_details/footer/goods_details_footer_widget.dart View File

@@ -63,9 +63,7 @@ class _GoodsDetailsFooterContainerState extends State<_GoodsDetailsFooterContain

@override
void didChangeDependencies() {
_user = Provider
.of<UserInfoNotifier>(context)
.userInfo;
_user = Provider.of<UserInfoNotifier>(context).userInfo;
super.didChangeDependencies();
}

@@ -88,6 +86,12 @@ class _GoodsDetailsFooterContainerState extends State<_GoodsDetailsFooterContain

/// 收藏
void _collectOnClick(GoodsDetailsFooterModel model) {
///获取用户信息,未登录需要先登录
var _user = Provider.of<UserInfoNotifier>(context,listen: false).userInfo;
if (_user?.token == null || _user?.token?.length == 0) {
RouterUtil.goLogin(context);
return;
}
bool isCollect = model.isFav == '0';
if (isCollect) {
// 收藏
@@ -133,27 +137,23 @@ class _GoodsDetailsFooterContainerState extends State<_GoodsDetailsFooterContain
}

Widget _getMainWidget(GoodsDetailsFooterModel model) {
double height = MediaQuery
.of(context)
.padding
.bottom;
double height = MediaQuery.of(context).padding.bottom;
return SafeArea(
child: Container(
width: double.infinity,
padding: EdgeInsets.only(bottom: (height > 10 ? 0 : 8), top: 8, left: 12.5, right: 12.5),
decoration: BoxDecoration(
// boxShadow: [
// BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0), blurRadius: 5.0, spreadRadius: 2.0),
// BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0)),
// ],
// boxShadow: [
// BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0), blurRadius: 5.0, spreadRadius: 2.0),
// BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0)),
// ],
color: HexColor.fromHex(model?.bgColor),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(ParseUtil.stringParseDouble(model?.topLeftRadius)),
topRight: Radius.circular(ParseUtil.stringParseDouble(model?.topRightRadius)),
bottomLeft: Radius.circular(ParseUtil.stringParseDouble(model?.bottomLeftRadius)),
bottomRight: Radius.circular(ParseUtil.stringParseDouble(model?.bottomRightRadius)),
)
),
)),
child: Container(height: 44, child: _getMainWidet(model)),
),
);
@@ -165,7 +165,6 @@ class _GoodsDetailsFooterContainerState extends State<_GoodsDetailsFooterContain
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[

/// 首页与收藏
_getLeftWidget(model),

@@ -187,7 +186,7 @@ class _GoodsDetailsFooterContainerState extends State<_GoodsDetailsFooterContain
behavior: HitTestBehavior.opaque,
onTap: () => _openHome(),
child: Padding(
padding: const EdgeInsets.only(right: 35,left: 8),
padding: const EdgeInsets.only(right: 35, left: 8),
child: _getCustomWidget(model?.listStyle?.leftIcon1?.text ?? '首页', model?.listStyle?.leftIcon1?.color ?? '999999', model?.listStyle?.leftIcon1?.beforeIcon ?? ''),
)),
),
@@ -213,8 +212,8 @@ class _GoodsDetailsFooterContainerState extends State<_GoodsDetailsFooterContain
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
(model?.listStyle?.rightIcon1?.isShow ?? "0") == "1" ? Expanded(child: _getFxzButton(model)):Container(),
(model?.listStyle?.rightIcon2?.isShow ?? "0") == "1" ? Expanded(child: _getZgsButton(model)):Container()
(model?.listStyle?.rightIcon1?.isShow ?? "0") == "1" ? Expanded(child: _getFxzButton(model)) : Container(),
(model?.listStyle?.rightIcon2?.isShow ?? "0") == "1" ? Expanded(child: _getZgsButton(model)) : Container()
],
),
);
@@ -242,10 +241,10 @@ class _GoodsDetailsFooterContainerState extends State<_GoodsDetailsFooterContain
width: double.infinity,
// padding: const EdgeInsets.only(left: 30, right: 30, top: 5, bottom: 5),
decoration: BoxDecoration(
// gradient: LinearGradient(
// colors: [HexColor.fromHex(/*model?.share_earn_bg1_color ??*/ '#FFCA66'), HexColor.fromHex(/*model?.share_earn_bg2_color ??*/ '#FFD961')],
// begin: Alignment.centerLeft,
// end: Alignment.centerRight),
// gradient: LinearGradient(
// colors: [HexColor.fromHex(/*model?.share_earn_bg1_color ??*/ '#FFCA66'), HexColor.fromHex(/*model?.share_earn_bg2_color ??*/ '#FFD961')],
// begin: Alignment.centerLeft,
// end: Alignment.centerRight),
image: DecorationImage(image: CachedNetworkImageProvider(model?.listStyle?.rightIcon1?.bgImage ?? ''), fit: BoxFit.fitWidth),
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(25), topLeft: Radius.circular(25))),
child: Column(
@@ -284,10 +283,10 @@ class _GoodsDetailsFooterContainerState extends State<_GoodsDetailsFooterContain
// padding: const EdgeInsets.only(left: 30, right: 30, top: 5, bottom: 5),
height: 44,
decoration: BoxDecoration(
// gradient: LinearGradient(
// colors: [HexColor.fromHex(/*model?.save_earn_bg1_color ??*/ '#FF6969'), HexColor.fromHex(/*model?.save_earn_bg2_color ??*/ '#FF4646')],
// begin: Alignment.centerLeft,
// end: Alignment.centerRight),
// gradient: LinearGradient(
// colors: [HexColor.fromHex(/*model?.save_earn_bg1_color ??*/ '#FF6969'), HexColor.fromHex(/*model?.save_earn_bg2_color ??*/ '#FF4646')],
// begin: Alignment.centerLeft,
// end: Alignment.centerRight),
image: DecorationImage(image: CachedNetworkImageProvider(model?.listStyle?.rightIcon2?.bgImage ?? ''), fit: BoxFit.fitWidth),
borderRadius: BorderRadius.only(bottomRight: Radius.circular(25), topRight: Radius.circular(25))),
child: Column(
@@ -319,7 +318,6 @@ class _GoodsDetailsFooterContainerState extends State<_GoodsDetailsFooterContain
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[

/// 图标
CachedNetworkImage(
imageUrl: icon,


Loading…
Cancel
Save