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.
 
 
 
 
 
 

406 lines
13 KiB

import 'dart:ui';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:geolocator/geolocator.dart';
import 'package:huixiang/generated/l10n.dart';
import 'package:huixiang/main.dart';
import 'package:huixiang/retrofit/data/address.dart';
import 'package:huixiang/retrofit/data/ip_data.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/union/union_list.dart';
import 'package:huixiang/utils/event_type.dart';
import 'package:huixiang/utils/location.dart';
import 'package:huixiang/view_widget/my_tab.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:visibility_detector/visibility_detector.dart';
import '../view_widget/location_tips.dart';
import '../view_widget/no_data_view.dart';
class UnionPage extends StatefulWidget {
final int initialIndex;
UnionPage(Key key, this.initialIndex) : super(key: key);
@override
State<StatefulWidget> createState() {
return UnionPageState();
}
}
class UnionPageState extends State<UnionPage>
with
AutomaticKeepAliveClientMixin,
WidgetsBindingObserver,
SingleTickerProviderStateMixin {
final TextEditingController editingController = TextEditingController();
bool isKeyBoardShow = false;
TabController tabController;
Position latLng;
String areaName;
List<GlobalKey> _allKey = [];
bool _isShowLocalTips = false;
double visiblePercentage;
jumpIndex(jpIndex) {
tabController.index = jpIndex;
}
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
// if (LocationInstance.getInstance() != null &&
// LocationInstance.getInstance().location != null)
// LocationInstance.getInstance().location.stopLocation();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// 处理应用程序切换回前台的逻辑
if(visiblePercentage == 1)
permissionSettings();
} else if (state == AppLifecycleState.paused) {
// 处理应用程序切换到后台的逻辑
}
}
void permissionSettings() async {
if (_isShowLocalTips && await Permission.location.isGranted){
_isShowLocalTips = false;
getLocation();
}
}
@override
void didChangeMetrics() {
super.didChangeMetrics();
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
print("object: ${MediaQuery.of(context).viewInsets.bottom}");
if (MediaQuery.of(context).viewInsets.bottom == 0) {
if (isKeyBoardShow) {
isKeyBoardShow = false;
//关闭键盘 软键盘关闭了, 清除输入控件的焦点, 否则重新进入页面会导致软键盘再弹出问题
FocusScope.of(context).requestFocus(FocusNode());
}
} else {
isKeyBoardShow = true;
}
});
});
}
@override
void initState() {
super.initState();
tabController = TabController(
length: 4, vsync: this, initialIndex: widget.initialIndex);
WidgetsBinding.instance.addObserver(this);
eventBus.on<EventType>().listen((event) {
if (event.type < 3) {
setState(() {});
}
});
queryIpInfo();
}
getLocation({bool showLoading = true}) async {
if(showLoading)
EasyLoading.show(
status: S.current.zhengzaijiazai,
maskType: EasyLoadingMaskType.black,
);
bool powerFlag = false;
// bool finallyFlag = false;
try {
powerFlag = await LocationInstance.getInstance().startLocation(context,
(Position result) async {
if (result != null &&
result.latitude != null &&
result.longitude != null) {
print("location: $result");
latLng = Position(
latitude: result.latitude,
longitude: result.longitude,
);
Address address = await LocationInstance.getInstance().getAddress(result.latitude, result.longitude);
if (address != null) {
await saveLatLng(latLng, address.province, address.city, address.area);
areaName = address.city.replaceAll("", "");
}
LocationInstance.getInstance().stopLocation();
} else {
await getLatLng();
}
loadFinish(showLoading: false);
});
} finally {
// finallyFlag = true;
if (!powerFlag) {
if (await Permission.locationWhenInUse.status.isGranted) {
getLocation();
} else {
_isShowLocalTips = true;
loadFinish(showLoading: false);
}
}
}
}
saveLatLng(Position latLng, province, city, district) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString("latitude", "${latLng.latitude}");
await prefs.setString("longitude", "${latLng.longitude}");
if (province != null) await prefs.setString("province", province);
if (city != null) await prefs.setString("city", city);
if (district != null) await prefs.setString("district", district);
}
getLatLng() async {
var tempLatLng = await SharedPreferences.getInstance();
if (tempLatLng.containsKey("latitude") &&
tempLatLng.containsKey("longitude") &&
tempLatLng.containsKey("province") &&
tempLatLng.containsKey("city") &&
tempLatLng.containsKey("district")) {
latLng = Position(
latitude: double.tryParse(tempLatLng.getString("latitude")),
longitude: double.tryParse(tempLatLng.getString("longitude")),
);
}
}
queryIpInfo() async {
EasyLoading.show(
status: S.current.zhengzaijiazai,
maskType: EasyLoadingMaskType.black,
);
try {
ApiService apiIpService = ApiService(Dio(), context: context, isIp: true);
IpData baseData = await apiIpService.getIpInfo().catchError((onError) {});
if (baseData?.city != null) {
areaName = baseData.city.replaceAll("", "");
}
} finally {
getLocation(showLoading: false);
}
}
loadFinish({bool showLoading = true}) {
if (showLoading)
EasyLoading.show(
status: S.current.zhengzaijiazai,
maskType: EasyLoadingMaskType.black,
);
_allKey = [GlobalKey(), GlobalKey(), GlobalKey(), GlobalKey()];
setState(() {});
}
@override
Widget build(BuildContext context) {
super.build(context);
return VisibilityDetector(
key: Key('my-widget-key'),
onVisibilityChanged: (visibilityInfo) {
visiblePercentage = visibilityInfo.visibleFraction;
if(visiblePercentage == 1)
permissionSettings();
},
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Container(
child: Column(
children: [
Row(
children: [
Padding(
padding: EdgeInsets.only(left: 18.w, right: 10.w),
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
Navigator.of(context).pushNamed(
'/router/union_select_city',
arguments: {"cityName": areaName}).then((value) {
if (value != null) {
areaName = value;
loadFinish();
}
});
},
child: Row(
children: [
Text(
areaName ?? "",
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.bold,
color: Colors.white),
),
Icon(
Icons.keyboard_arrow_down,
color: Colors.white,
size: 24,
)
],
),
),
),
Expanded(child: buildSearchItem())
],
),
Align(
alignment: Alignment.centerLeft,
child: TabBar(
controller: tabController,
isScrollable: true,
//可滚动
indicatorColor: Colors.white,
labelColor: Colors.white,
labelStyle: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
),
unselectedLabelStyle: TextStyle(
fontSize: 15.sp,
fontWeight: FontWeight.normal,
),
//未选中文字颜色
unselectedLabelColor: Colors.white,
indicatorSize: TabBarIndicatorSize.label,
//指示器与文字等宽
tabs: <Widget>[
MyTab(text: S.of(context).quanbu),
MyTab(text: S.of(context).chi),
MyTab(text: S.of(context).he),
MyTab(text: S.of(context).wan),
],
),
),
_allKey.isEmpty
? NoDataView(
src: "assets/image/di_zhi.webp",
isShowBtn: false,
text: "暂无店铺列表~",
fontSize: 16.sp,
margin: EdgeInsets.only(top: 120.h),
)
: Expanded(
child: TabBarView(
controller: tabController,
children: [
UnionList(_allKey[0], "", latLng,
editingController.text, areaName),
UnionList(_allKey[1], "EATSTORE", latLng,
editingController.text, areaName),
UnionList(_allKey[2], "DRINKSTORE", latLng,
editingController.text, areaName),
UnionList(_allKey[3], "HAPPYSTORE", latLng,
editingController.text, areaName),
],
),
)
],
),
padding:
EdgeInsets.only(top: MediaQuery.of(context).padding.top + 17.h),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF32A060),
Color(0xFF32A060),
Colors.white,
Colors.white,
],
stops: [
0,
0.2,
0.4,
1
]),
),
),
if (_isShowLocalTips)
Padding(
padding: EdgeInsets.only(bottom: 70.h),
child: LocationTips(() {
setState(() {
_isShowLocalTips = false;
});
}),
)
],
),
));
}
Widget buildSearchItem() {
return Container(
margin: EdgeInsets.fromLTRB(6.w, 0, 14.w, 0),
padding: EdgeInsets.symmetric(vertical: 6.h),
decoration: BoxDecoration(
color: Color(0xFFF5FAF7),
borderRadius: BorderRadius.circular(4),
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(12),
offset: Offset(0, 3),
blurRadius: 14,
spreadRadius: 0,
),
],
),
child: TextField(
textInputAction: TextInputAction.search,
onEditingComplete: () {
FocusScope.of(context).requestFocus(FocusNode());
loadFinish();
},
controller: editingController,
style: TextStyle(
fontSize: 14.sp,
),
decoration: InputDecoration(
hintText: "搜索联盟会员店",
hintStyle: TextStyle(
fontSize: 12.sp,
color: Color(0xFFB3B3B3),
),
isCollapsed: true,
prefixIcon: Padding(
padding: EdgeInsets.only(left: 5.w, right: 5.w),
child: Image.asset(
"assets/image/icon_search.webp",
width: 16.h,
height: 16.h,
),
),
prefixIconConstraints: BoxConstraints(),
border: InputBorder.none,
),
),
);
}
@override
bool get wantKeepAlive => true;
}