You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

467 lines
14 KiB

4 years ago
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
4 years ago
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
4 years ago
import 'package:flutter_html/flutter_html.dart';
4 years ago
import 'package:flutter_swiper_null_safety/flutter_swiper_null_safety.dart';
import 'package:huixiang/generated/l10n.dart';
4 years ago
import 'package:huixiang/retrofit/data/base_data.dart';
import 'package:huixiang/retrofit/data/brand_data.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/view_widget/classic_header.dart';
import 'package:huixiang/view_widget/custom_image.dart';
4 years ago
import 'package:huixiang/view_widget/icon_text.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
4 years ago
import 'package:huixiang/view_widget/loading_view.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:html/parser.dart' as htmlparser;
import 'package:html/dom.dart' as dom;
4 years ago
class BrandPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _BrandPage();
}
}
4 years ago
class _BrandPage extends State<BrandPage>
with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
4 years ago
ScrollController tabcontroller;
List<String> tabs = [
S.current.bainianchuanjiao,
S.current.haixiajiemei,
S.current.qianjinmaiwei,
];
Map<String, String> images = {
S.current.bainianchuanjiao: "assets/image/icon_chili.png",
S.current.haixiajiemei: "assets/image/icon_milk_tea.png",
S.current.qianjinmaiwei: "assets/image/icon_bread.png",
};
GlobalKey chiliGlobalKey = GlobalKey();
GlobalKey milkTeaGlobalKey = GlobalKey();
GlobalKey breadGlobalKey = GlobalKey();
4 years ago
ApiService apiService;
BrandData brandData;
queryHome() async {
showCupertinoDialog(
context: context,
barrierDismissible: true,
builder: (context) {
return LoadingView();
});
BaseData baseData = await apiService.queryHome().catchError((error) {
refreshController.refreshFailed();
});
if (Navigator.canPop(context)) Navigator.of(context).pop();
if (baseData.isSuccess) {
refreshController.refreshCompleted();
brandData = BrandData.fromJson(baseData.data);
setState(() {});
} else {
refreshController.refreshFailed();
}
}
4 years ago
@override
void initState() {
super.initState();
4 years ago
SharedPreferences.getInstance().then((value) => {
apiService = ApiService(Dio(), token: value.getString('token')),
queryHome(),
});
4 years ago
if (tabcontroller == null) tabcontroller = ScrollController();
tabcontroller.addListener(() {
// RenderBox contentRenderBox = contentGlobalKey.currentContext.findRenderObject();
RenderBox chiliRenderBox =
chiliGlobalKey.currentContext.findRenderObject();
RenderBox milkTeaRenderBox =
milkTeaGlobalKey.currentContext.findRenderObject();
RenderBox breadRenderBox =
breadGlobalKey.currentContext.findRenderObject();
// Offset contentOffset = contentRenderBox.localToGlobal(Offset.zero);
Offset chiliOffset = chiliRenderBox.localToGlobal(Offset.zero);
Offset milkTeaOffset = milkTeaRenderBox.localToGlobal(Offset.zero);
Offset breadOffset = breadRenderBox.localToGlobal(Offset.zero);
4 years ago
// print("chiliOffset: ${chiliOffset.dy}");
// print("milkTeaOffset: ${milkTeaOffset.dy}");
// print("breadOffset: ${breadOffset.dy}");
4 years ago
var top = 96.h;
if (chiliOffset.dy <= top) {
if (!isVisible) {
isVisible = true;
}
} else {
isVisible = false;
selectedIndex = "";
}
if (chiliOffset.dy <= top && milkTeaOffset.dy > top) {
selectedIndex = tabs[0];
} else if (milkTeaOffset.dy <= top && breadOffset.dy > top) {
selectedIndex = tabs[1];
} else if (breadOffset.dy <= top) {
selectedIndex = tabs[2];
}
setState(() {});
});
}
String selectedIndex = "";
4 years ago
RefreshController refreshController = RefreshController();
4 years ago
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 40 - MediaQuery.of(context).padding.top,
backgroundColor: Colors.white,
elevation: 0,
),
body: Container(
// key: contentGlobalKey,
child: Stack(
children: [
Container(
4 years ago
child: SmartRefresher(
controller: refreshController,
enablePullDown: true,
enablePullUp: false,
header: MyHeader(),
4 years ago
physics: BouncingScrollPhysics(),
4 years ago
scrollController: tabcontroller,
onRefresh: queryHome,
child: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Container(
color: Color(0xFFF7F7F7),
margin: EdgeInsets.only(top: 16),
child: Column(
children: homeChildItem(),
),
4 years ago
),
),
),
),
Positioned(
child: Visibility(
visible: isVisible,
child: Container(
width: MediaQuery.of(context).size.width,
child: Container(
height: 52.h,
color: Colors.white,
4 years ago
padding: EdgeInsets.all(6),
alignment: Alignment.center,
4 years ago
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
4 years ago
children:
tabs.map((e) => item(e, selectedIndex == e)).toList(),
4 years ago
),
),
),
),
top: 0,
),
],
),
),
);
}
4 years ago
List<Widget> homeChildItem() {
var widgets = <Widget>[banner(), buildInfo(), buildTab()];
if (brandData == null) return widgets;
(brandData.contents as Map<String, dynamic>).forEach((key, value) {
dom.Document document = htmlparser.parse(value);
widgets.add(Container(
key: key == "百年川椒"
? chiliGlobalKey
: key == "海峡姐妹"
? milkTeaGlobalKey
: breadGlobalKey,
child: Html(
data:
"""<p><img class=\"wscnph\" src=\"blob:http://192.168.10.195:8082/bead76d2-cee4-4d54-906c-139a03328b8f\" /><img class=\"wscnph\" src=\"blob:http://192.168.10.195:8082/6bf9b43a-7f95-4fa5-abfb-a0542f167cbb\" /></p>""",
),
));
});
return widgets;
}
4 years ago
bool isVisible = false;
Widget buildTab() {
return Container(
// key: tabGlobalKey,
height: 52.h,
4 years ago
padding: EdgeInsets.all(6),
alignment: Alignment.center,
4 years ago
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: tabs.map((e) => item(e, selectedIndex == e)).toList(),
),
);
}
Widget item(text, isSelected) {
return GestureDetector(
onTap: () {
FlexParentData parendData;
if (text == S.of(context).bainianchuanjiao) {
parendData =
chiliGlobalKey.currentContext.findRenderObject().parentData;
} else if (text == S.of(context).haixiajiemei) {
parendData =
milkTeaGlobalKey.currentContext.findRenderObject().parentData;
} else if (text == S.of(context).qianjinmaiwei) {
parendData =
breadGlobalKey.currentContext.findRenderObject().parentData;
}
double offset = parendData.offset.dy - 52.h + 20;
tabcontroller.animateTo(offset,
duration: Duration(seconds: 1), curve: Curves.ease);
},
child: tabItem(text, selectedIndex == text),
);
}
Widget tabItem(text, isSelected) {
if (isSelected) {
return IconText(
text,
isMax: false,
4 years ago
rightImage: images[text],
iconSize: 16,
iconColor: Colors.red,
textStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: Color(0xFF353535)),
);
} else {
return IconText(
text,
isMax: false,
4 years ago
textStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: Color(0xFF353535)),
);
}
}
Widget buildInfo() {
return Container(
margin: EdgeInsets.only(bottom: 20, top: 16),
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(12),
offset: Offset(0, 2),
blurRadius: 14,
spreadRadius: 0)
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
ClipOval(
4 years ago
child: MImage(
brandData == null ? "" : brandData.originAvatar,
4 years ago
fit: BoxFit.cover,
width: 60,
height: 60,
4 years ago
errorSrc: "assets/image/default_1.png",
fadeSrc: "assets/image/default_1.png",
4 years ago
),
clipBehavior: Clip.hardEdge,
),
SizedBox(
width: 16,
),
Expanded(
child: Container(
height: 60,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text.rich(
TextSpan(children: [
TextSpan(
4 years ago
text: brandData == null ? "" : brandData.originator,
4 years ago
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: Colors.black),
),
TextSpan(
text: " 集团创办人",
style: TextStyle(fontSize: 10, color: Colors.black),
),
]),
textDirection: TextDirection.ltr,
),
Text(
4 years ago
brandData == null ? "" : brandData.originDesc,
4 years ago
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: TextStyle(
fontSize: 12,
color: Color(0xFF353535),
),
),
],
),
),
flex: 1,
)
],
),
SizedBox(
height: 40,
),
Text(
4 years ago
brandData == null ? "" : brandData.company,
4 years ago
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.bold,
color: Colors.black),
),
SizedBox(
height: 20,
),
Text(
4 years ago
brandData == null ? "" : brandData.companyDesc,
4 years ago
textAlign: TextAlign.justify,
style: TextStyle(fontSize: 12.sp, color: Color(0xFF353535)),
),
SizedBox(
height: 40,
),
Text(
"理念",
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.bold,
color: Colors.black),
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
4 years ago
children: buildIdea(),
4 years ago
),
],
),
);
}
4 years ago
List<Widget> buildIdea() {
if (brandData == null) return [];
var ideas = <Widget>[];
(brandData.ideals as Map<String, dynamic>).forEach((key, value) {
ideas.add(idea(key, value));
});
return ideas;
}
4 years ago
banner() {
return Container(
child: AspectRatio(
aspectRatio: 2.08,
child: Swiper(
viewportFraction: 0.88,
scale: 0.93,
pagination: SwiperPagination(
alignment: Alignment.bottomCenter,
builder: DotSwiperPaginationBuilder(
size: 8,
activeSize: 8,
space: 5,
activeColor: Colors.black,
color: Colors.black.withAlpha(76),
),
),
itemBuilder: (context, position) {
4 years ago
return MImage(
(brandData != null &&
brandData.bannerList != null &&
position < brandData.bannerList.length)
? brandData.bannerList[position].imgUrl
: "",
fit: BoxFit.cover,
radius: BorderRadius.circular(8),
errorSrc: "assets/image/default_2_1.png",
fadeSrc: "assets/image/default_2_1.png",
);
4 years ago
},
4 years ago
itemCount: (brandData != null && brandData.bannerList != null)
? brandData.bannerList.length
: 1),
4 years ago
),
);
}
4 years ago
Widget idea(key, value) {
4 years ago
return Stack(
children: [
4 years ago
MImage(
value,
width: 71,
height: 71,
fit: BoxFit.cover,
errorSrc: "assets/image/default_1.png",
fadeSrc: "assets/image/default_1.png",
4 years ago
),
Positioned(
bottom: 0,
child: Container(
width: 71,
decoration: BoxDecoration(
color: Colors.black.withAlpha(125),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(4),
bottomLeft: Radius.circular(4),
),
),
padding: EdgeInsets.symmetric(vertical: 2),
alignment: Alignment.center,
child: Text(
4 years ago
key,
4 years ago
style: TextStyle(
color: Colors.white,
fontSize: 12.sp,
),
),
),
)
],
);
}
4 years ago
@override
bool get wantKeepAlive => true;
4 years ago
}