Commit 88fe4c9a authored by 汪林玲's avatar 汪林玲

升级到Flutter2.5.1

parents
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
.vscode/
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 1aafb3a8b9b0c36241c5f5b34ee914770f015818
channel: stable
project_type: package
## [0.0.1] - TODO: Add release date.
* TODO: Describe initial release.
TODO: Add your license here.
lifeChannel.shopOther recommend_list 差团购购买链接
全部评价接口
店铺详情需要 经纬度
秒杀板块显示单个配置项
宣传口-吃喝玩乐
宣传口-生活秒杀
### 引入说明
```
life_module:
git:
url: 'git@git.xiaomanxiong.com:flutter-plugin/life_module.git'
ref: 'null-safety'
```
\ No newline at end of file
This diff is collapsed.
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:life_repository/life_repository.dart';
import 'package:common_module/utils/date_time_helper.dart';
class AppraiseItem extends StatelessWidget {
final ShopCommentItemEntity item;
AppraiseItem(this.item);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(
top: 16.rpx, bottom: 20.rpx, left: 12.rpx, right: 12.rpx),
color: Colors.white,
child: Column(
children: [
Container(
child: Text(
item.comment,
style: TextStyle(color: rgba(48, 38, 0, 1), fontSize: 13.rpx),
),
),
SizedBox(
height: 6.rpx,
),
_ScoreInfo(item),
],
),
);
}
}
/// 评分和距离信息
class _ScoreInfo extends StatelessWidget {
final ShopCommentItemEntity item;
_ScoreInfo(this.item);
@override
Widget build(BuildContext context) {
List<InlineSpan> widgets = [];
double score = double.parse(item.star);
for (int star = 1, len = score.ceil(); star <= len; star++) {
widgets.add(WidgetSpan(
child: Image.asset(
star <= score
? "assets/ic_star_small_full.png"
: "assets/ic_star_small_half.png",
width: 12.rpx,
height: 12.rpx,
)));
}
for (int star = widgets.length; star < 5; star++) {
widgets.add(WidgetSpan(
child: Image.asset(
"assets/ic_star_small_blank.png",
width: 12.rpx,
height: 12.rpx,
)));
}
widgets.add(WidgetSpan(
child: SizedBox(
width: 2.rpx,
)));
return Container(
height: 18.rpx,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
alignment: Alignment.centerLeft,
height: 14.rpx,
child: Text.rich(TextSpan(children: widgets)),
),
Container(
child: Text(double.parse(item.star).toStringAsFixed(1),
style: TextStyle(
color: rgba(255, 128, 0, 1),
fontSize: 14.rpx,
fontWeight: FontWeight.bold,
)),
),
Spacer(),
Text(
DateUtil.formatDateStr(item.createTime,format: "yyyy-MM-dd HH:mm:ss"),
style: TextStyle(color: rgba(153, 153, 153, 1), fontSize: 11.rpx),
)
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:life_module/utils/filter_panel_utils.dart';
import 'package:mvp/mvp.dart';
import 'package:life_module/models/filter_model.dart';
class FilterArea extends StatefulWidget {
final FilterModel model;
final Function(bool checked) onTap;
final Function() onChange;
final double topOffset;
FilterArea({this.model, this.onTap, this.topOffset, this.onChange});
@override
State<StatefulWidget> createState() => _FilterAreaState();
}
class _FilterAreaState extends State<FilterArea> {
Function() _onChange;
@override
void initState() {
this._onChange = widget.onChange;
super.initState();
}
@override
Widget build(BuildContext context) {
return QMProvider<FilterModel>.value(
model: widget.model,
builderWidget: (context, model, child) {
if (model.isEmpty()) {
return Container(
height: 48.rpx,
);
}
String regionName = '';
if (model.getCheckedTwoRegion() != null &&
model.getCheckedTwoRegion().name != null) {
regionName = model.getCheckedTwoRegion().name;
} else if (model.getCheckedOneRegion() != null) {
regionName = model.getCheckedOneRegion().name;
}
return Container(
height: 48.rpx,
padding: EdgeInsets.symmetric(horizontal: 1.rpx),
color: rgba(245, 245, 245, 1),
transform: Matrix4.translationValues(0, -1, 0),
child: Row(
children: [
_FilterItem(
text: model.getCheckedOneCategory().name,
checked: model.getFilterAreaIndex() == 1,
onTap: (checked) {
if (widget.onTap != null) {
widget.onTap(checked);
}
if (checked) {
return;
}
model.stFilterAreaIndex(1);
FilterPanelUtils.show(
topOffset: widget.topOffset,
items: model.getCategorys(),
oneCheckedId: model.getCheckedOneCategory().id,
twoCheckedId: model.getCheckedTwoCategory().id,
context: context,
model: model,
onClose: () {
model.stFilterAreaIndex(0);
},
onChange:this._onChange,
onConfirm: (onwItem, twoItem) {
model.stFilterAreaIndex(0);
model.setCheckedCategory(onwItem, twoItem);
if(_onChange != null){
_onChange();
}
});
},
),
_FilterItem(
text: regionName,
checked: model.getFilterAreaIndex() == 2,
onTap: (checked) {
if (widget.onTap != null) {
widget.onTap(checked);
}
if (checked) {
return;
}
model.stFilterAreaIndex(2);
FilterPanelUtils.show(
topOffset: widget.topOffset,
items: model.getRegions(),
oneCheckedId: model.getCheckedOneRegion().id,
twoCheckedId: model.getCheckedTwoRegion().id,
context: context,
model: model,
onClose: () {
model.stFilterAreaIndex(0);
},
onChange:this._onChange,
onConfirm: (onwItem, twoItem) {
model.stFilterAreaIndex(0);
model.setCheckedRegion(onwItem, twoItem);
if(_onChange != null){
_onChange();
}
});
},
),
_FilterItem(
text: model.getCheckedOneSort().name,
checked: model.getFilterAreaIndex() == 3,
onTap: (checked) {
if (widget.onTap != null) {
widget.onTap(checked);
}
if (checked) {
return;
}
model.stFilterAreaIndex(3);
FilterPanelUtils.show(
topOffset: widget.topOffset,
items: model.getSorts(),
oneCheckedId: model.getCheckedOneSort().id,
twoCheckedId: model.getCheckedTwoSort().id,
context: context,
model: model,
onClose: () {
model.stFilterAreaIndex(0);
},
onChange:this._onChange,
onConfirm: (onwItem, twoItem) {
model.stFilterAreaIndex(0);
model.setCheckedSort(onwItem, twoItem);
if(_onChange != null){
_onChange();
}
});
},
),
],
),
);
},
);
}
}
class _FilterItem extends StatelessWidget {
final bool checked;
final String text;
final Function(bool checked) onTap;
_FilterItem({this.text, this.onTap, this.checked = false});
@override
Widget build(BuildContext context) {
Color textColor = rgba(48, 38, 0, 1);
Color iconColor = rgba(151, 151, 151, 1);
if (checked) {
textColor = rgba(255, 128, 0, 1);
iconColor = textColor;
}
String clipText = text;
if (clipText.length > 5) {
clipText = "${text.substring(0, 5)}...";
}
return Expanded(
child: GestureDetector(
onTap: () {
onTap(checked);
},
child: Container(
height: 48.rpx,
padding: EdgeInsets.only(
left: 6.rpx,
right: 6.rpx,
bottom: checked ? 0 : 8.rpx,
top: 12.rpx),
child: Container(
padding: EdgeInsets.only(
bottom: checked ? 8.rpx : 0,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(4.rpx),
topRight: Radius.circular(4.rpx),
bottomLeft: Radius.circular(checked ? 0 : 4.rpx),
bottomRight: Radius.circular(checked ? 0 : 4.rpx))),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Text(
clipText,
overflow: TextOverflow.clip,
style: TextStyle(
color: textColor, fontSize: 14.rpx, height: 1.rpx),
),
),
Icon(checked ? Icons.arrow_drop_up : Icons.arrow_drop_down,
size: 13.rpx, color: iconColor)
],
),
),
),
),
);
}
}
This diff is collapsed.
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:life_module/components/type_icon.dart';
import 'package:life_repository/life_repository.dart';
import 'package:common_module/widget/xiaoxiong_base_image_widget/widget.dart';
class GoodsItem extends StatelessWidget {
final ComboItem item;
final Function() onTap;
GoodsItem({this.item, this.onTap});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Container(
height: 98.rpx,
margin: EdgeInsets.only(left: 13.rpx, right: 13.rpx, bottom: 8.rpx),
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(8.rpx)),
child: Row(
children: [
SizedBox(
width: 12.rpx,
),
ClipRRect(
borderRadius: BorderRadius.circular(8.rpx),
child: Container(
height: 74.rpx,
width: 74.rpx,
child: XiaoxiongBaseImageWidget(
imageUrl: item.shopImg,
height: 74.rpx,
width: 74.rpx,
),
)),
SizedBox(
width: 10.rpx,
),
Expanded(
child: Container(
height: 74.rpx,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_Title(item),
_PriceInfo(item),
_LocaionInfo(item)
],
),
),
),
SizedBox(
width: 12.rpx,
),
],
),
),
);
}
}
//、 标题
class _Title extends StatelessWidget {
final ComboItem item;
_Title(this.item);
@override
Widget build(BuildContext context) {
return Container(
height: 22.rpx,
child: Row(
children: [
TypeIcon(
type: int.parse(item.dealType),
),
SizedBox(
width: 5.rpx,
),
Expanded(
child: Container(
child: Text(
item.itemTitle,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(
fontSize: 15.rpx, fontWeight: FontWeight.bold, height: 1.rpx),
),
))
],
),
);
}
}
/// 价格信息
class _PriceInfo extends StatelessWidget {
final ComboItem item;
_PriceInfo(this.item);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 6.rpx),
height: 19.rpx,
child: Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
children: [
Text(
"¥",
style: TextStyle(
color: rgba(255, 4, 0, 1),
fontSize: 11.rpx,
),
),
Text(
item.endPrice,
style: TextStyle(
color: rgba(255, 4, 0, 1),
fontSize: 16.rpx,
),
),
SizedBox(
width: 4.rpx,
),
Text(
${item.originalPrice}",
style: TextStyle(
color: rgba(153, 153, 153, 1),
fontSize: 12.rpx,
decoration: TextDecoration.lineThrough),
),
SizedBox(
width: 12.rpx,
),
Container(
padding: EdgeInsets.symmetric(horizontal: 4.rpx, vertical: 2.rpx),
decoration: BoxDecoration(
border: Border.all(color: rgba(255, 128, 0, 1), width: 0.5),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(9.rpx),
topRight: Radius.circular(9.rpx),
bottomRight: Radius.circular(9.rpx))),
child: Text(
item.userCommissionText,
style: TextStyle(
color: rgba(255, 128, 0, 1), fontSize: 11.rpx, height: 1.2),
),
),
],
),
);
}
}
/// 定位信息
class _LocaionInfo extends StatelessWidget {
final ComboItem item;
_LocaionInfo(this.item);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 9.rpx),
height: 18.rpx,
width: double.infinity,
child: Row(
children: [
Container(
constraints: BoxConstraints(maxWidth: 190.rpx),
child: Text(
item.shopTitle,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: rgba(102, 102, 102, 1), fontSize: 11.rpx, height: 1.2),
),
),
SizedBox(
width: 2.rpx,
),
/*LifeImage(
name: "assets/images/life/ic_miaosha_arrow_right.png",
width: 8.rpx,
height: 8.rpx,
),*/
Spacer(),
Text(
item.distance,
style: TextStyle(
color: rgba(102, 102, 102, 1), fontSize: 11.rpx, height: 1.2),
),
],
),
);
}
}
import 'package:flutter/material.dart';
class LifeImage extends StatelessWidget {
final String name;
final double width;
final double height;
final Color color;
final BoxFit fit;
LifeImage({
Key key,
this.name,
this.width,
this.height,
this.color,
this.fit,
});
@override
Widget build(BuildContext context) {
return Image.asset(
name,
key: key,
width: width,
height: height,
color: color,
fit: fit,
package: "life_module",
);
}
}
export 'package:common_module/delegates/persistent_header_delegate.dart';
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
class SearchBar extends StatefulWidget {
final Color inputColor;
final bool enabled;
final FocusNode focusNode;
final Function(String) onSubmitted;
final Function(String) onChanged;
final TextEditingController controller;
SearchBar(
{this.enabled = false,
this.inputColor,
this.focusNode,
this.onChanged,
this.onSubmitted,
this.controller});
@override
State<StatefulWidget> createState() => _SearchBarState();
}
class _SearchBarState extends State<SearchBar> {
@override
Widget build(BuildContext context) {
return Container(
height: 34.rpx,
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
color: widget.inputColor,
borderRadius: BorderRadius.circular(17.rpx),
border: Border.all(color: rgba(255, 128, 0, 1), width: 1)),
child: Row(
children: [
_TextField(
enabled: widget.enabled,
onChanged: widget.onChanged,
onSubmitted: widget.onSubmitted,
focusNode: widget.focusNode,
controller: widget.controller),
!widget.enabled
? _Button()
: InkWell(
child: _Button(),
onTap: () {
widget.onSubmitted(widget.controller.text);
},
),
SizedBox(
width: 3.rpx,
)
],
),
);
}
}
class _TextField extends StatefulWidget {
final bool enabled;
final FocusNode focusNode;
final Function(String) onSubmitted;
final Function(String) onChanged;
final TextEditingController controller;
_TextField(
{this.enabled,
this.focusNode,
this.onChanged,
this.onSubmitted,
this.controller});
@override
State<StatefulWidget> createState() => _TextFieldState();
}
/// 输入框
class _TextFieldState extends State<_TextField> {
bool showCloseBtn = false;
@override
void initState() {
super.initState();
if (widget.controller != null) {
widget.controller.addListener(() {
setState(() {
showCloseBtn = widget.controller.text.isNotEmpty;
});
});
}
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Expanded(
child: Container(
height: 34.rpx,
alignment: Alignment.centerLeft,
child: Stack(
children: [
Container(
height: 34.rpx,
padding: EdgeInsets.only(right: 29.rpx),
child: TextField(
enabled: widget.enabled,
focusNode: widget.focusNode,
controller: widget.controller,
onSubmitted: widget.onSubmitted,
onChanged: widget.onChanged,
textAlignVertical: TextAlignVertical.center,
textInputAction: TextInputAction.search,
keyboardType: TextInputType.text,
style: TextStyle(color: rgba(48, 38, 0, 1), fontSize: 12.rpx),
decoration: InputDecoration(
fillColor: Colors.transparent,
prefixIconConstraints: BoxConstraints(maxWidth: 26.rpx),
prefixIcon: Container(
margin:
EdgeInsets.only(left: 8.rpx, right: 4.rpx, bottom: 2.rpx),
child: Image.asset("assets/ic_home_search.png",
width: 20.rpx, height: 20.rpx, fit: BoxFit.contain),
),
hintText: '搜索店铺,领隐藏优惠券省钱',
isDense: false,
hintStyle:
TextStyle(color: rgba(170, 170, 170, 1), fontSize: 12.rpx),
border: OutlineInputBorder(
borderSide: BorderSide(style: BorderStyle.none),
gapPadding: 0.0,
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(style: BorderStyle.none),
gapPadding: 0.0,
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(style: BorderStyle.none),
gapPadding: 0.0,
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(style: BorderStyle.none),
gapPadding: 0.0,
),
disabledBorder: OutlineInputBorder(
borderSide: BorderSide(style: BorderStyle.none),
gapPadding: 0.0,
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(style: BorderStyle.none),
gapPadding: 0.0,
),
contentPadding: EdgeInsets.all(0),
),
),
),
Builder(
builder: (context) {
if (!showCloseBtn) {
return SizedBox();
}
return Positioned(
right: 0,
top: 0,
child: InkWell(
onTap: () {
widget.onChanged("");
widget.onSubmitted("");
widget.controller.text = '';
widget.focusNode.requestFocus();
},
child: Container(
width: 34.rpx,
height: 34.rpx,
alignment: Alignment.center,
child: Image.asset(
"assets/close_btn_black.png",
width: 14.rpx,
height: 14.rpx,
),
),
),
);
},
)
],
),
));
}
}
/// 搜索按钮
class _Button extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 46.rpx,
height: 28.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
color: rgba(255, 128, 0, 1),
borderRadius: BorderRadius.circular(17.rpx)),
child: Text(
'搜索',
style: TextStyle(color: rgba(255, 255, 255, 1), fontSize: 13.rpx),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:navigation_bar/navigation_bar.dart';
import 'package:mvp/mvp.dart';
import 'package:life_module/models/filter_model.dart';
import 'package:life_repository/life_repository.dart';
class ShopClassNav extends StatefulWidget {
final FilterModel model;
final Function() onChange;
ShopClassNav({this.model, this.onChange});
@override
State<StatefulWidget> createState() => _ShopClassNavState();
}
class _ShopClassNavState extends State<ShopClassNav>
with TickerProviderStateMixin {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return QMProvider<FilterModel>.value(
model: widget.model,
builderWidget: (context, model, child) {
if (model.isEmpty()) {
return Container(
height: 40.rpx,
);
}
List<FilterItemEntity> subs = model.getCheckedOneCategory().subs;
return Container(
key: ValueKey(subs.map((e) => e.id).join('_')),
height: 40.rpx,
color: rgba(245, 245, 245, 1),
transform: Matrix4.translationValues(0, -1.5, 0),
child: NotificationListener(
child: NavigationBar(
controller: model.getShopClassNavTabController(),
items: subs.map((e) => e.name).toList(),
selectColor: rgba(255, 128, 0, 1),
normalColor: rgba(102, 102, 102, 1),
selectStyle: TextStyle(
fontSize: 13.rpx, height: 1, fontWeight: FontWeight.bold),
normalStyle: TextStyle(
fontSize: 13.rpx,
height: 1,
),
isScrollable: true,
onChange: (index) {
if (subs[index] == model.getCheckedTwoCategory()) {
return;
}
model.setCheckedCategory(
model.getCheckedOneCategory(), subs[index]);
widget.onChange();
},
indicatorSize: TabBarIndicatorSize.label,
indicator: RoundRectIndicator(
color: Colors.transparent, height: 0, marginBottom: 0),
),
onNotification: (e) {
return true;
},
),
);
});
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:life_module/components/type_icon.dart';
import 'package:life_repository/life_repository.dart';
import 'package:common_module/widget/xiaoxiong_base_image_widget/widget.dart';
class ShopItem extends StatelessWidget {
final RestaurantItem item;
final Function() onTap;
ShopItem({this.item, this.onTap});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Container(
margin: EdgeInsets.only(left: 13.rpx, right: 13.rpx, bottom: 8.rpx),
padding: EdgeInsets.symmetric(vertical: 12.rpx),
alignment: Alignment.topLeft,
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(8.rpx)),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 12.rpx,
),
ClipRRect(
borderRadius: BorderRadius.circular(8.rpx),
child: Container(
height: 74.rpx,
width: 74.rpx,
child: XiaoxiongBaseImageWidget(
imageUrl: item.shopImg,
height: 74.rpx,
width: 74.rpx,
),
)),
SizedBox(
width: 10.rpx,
),
Expanded(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_Title(item),
_ScoreInfo(item),
_LocaionInfo(item),
Container(
height: 0.5.rpx,
color: rgba(151, 151, 151, 0.1),
),
_GoodList(item)
],
),
),
),
SizedBox(
width: 12.rpx,
),
],
),
),
);
}
}
/// 标题
class _Title extends StatelessWidget {
final RestaurantItem item;
_Title(this.item);
@override
Widget build(BuildContext context) {
return Container(
height: 22.rpx,
child: Row(
children: [
Expanded(
child: Container(
child: Text(
item.shopTitle,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(
fontSize: 15.rpx, fontWeight: FontWeight.bold, height: 1.rpx),
),
))
],
),
);
}
}
/// 评分和销量信息
class _ScoreInfo extends StatelessWidget {
final RestaurantItem item;
_ScoreInfo(this.item);
@override
Widget build(BuildContext context) {
var showStarScore = item.showStarScore;
List<InlineSpan> widgets = [];
double score = double.parse(showStarScore);
for (int star = 1, len = score.ceil(); star <= len; star++) {
widgets.add(WidgetSpan(
child: Image.asset(
star <= score
? "assets/ic_star_small_full.png"
: "assets/ic_star_small_half.png",
width: 12.rpx,
height: 16.rpx,
)));
}
for (int star = widgets.length; star < 5; star++) {
widgets.add(WidgetSpan(
child: Image.asset(
"assets/ic_star_small_blank.png",
width: 12.rpx,
height: 16.rpx,
)));
}
widgets.add(WidgetSpan(
child: SizedBox(
width: 2.rpx,
)));
widgets.add(TextSpan(
text: double.parse(item.commentScore).toStringAsFixed(1),
style: TextStyle(
color: rgba(255, 128, 0, 1),
fontSize: 14.rpx,
fontWeight: FontWeight.bold)));
return Container(
height: 18.rpx,
margin: EdgeInsets.only(top: 4.rpx),
child: Row(
children: [
Container(
alignment: Alignment.centerLeft,
height: 14.rpx,
child: Text.rich(TextSpan(children: widgets)),
),
SizedBox(
width: 8.rpx,
),
Text(
" ",
style: TextStyle(color: rgba(102, 102, 102, 1), fontSize: 12.rpx),
),
Spacer(),
Text(
${item.avgPrice}/人",
style: TextStyle(color: rgba(102, 102, 102, 1), fontSize: 11.rpx),
)
],
),
);
}
}
/// 地址信息
class _LocaionInfo extends StatelessWidget {
final RestaurantItem item;
_LocaionInfo(this.item);
@override
Widget build(BuildContext context) {
return Container(
height: 18.rpx,
margin: EdgeInsets.only(top: 7.rpx, bottom: 8.rpx),
child: Row(
children: [
Text(
item.categoryName,
style: TextStyle(color: rgba(102, 102, 102, 1), fontSize: 11.rpx),
),
Spacer(),
Text(
"${item.regionName}${item.distance}",
style: TextStyle(color: rgba(102, 102, 102, 1), fontSize: 11.rpx),
)
],
),
);
}
}
class _GoodList extends StatelessWidget {
final RestaurantItem item;
_GoodList(this.item);
@override
Widget build(BuildContext context) {
List<Widget> items = item.itemList.map((e) {
return _GoodItem(e);
}).toList();
return Container(
child: Column(
children: items,
),
);
}
}
/// 代金券和团购单个信息
class _GoodItem extends StatelessWidget {
final ShopSubItemList item;
_GoodItem(this.item);
@override
Widget build(BuildContext context) {
return Container(
height: 16.rpx,
margin: EdgeInsets.only(top: 9.rpx),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TypeIcon(type: int.parse(item.dealType)),
SizedBox(
width: 6.rpx,
),
_PriceInfo(item),
SizedBox(
width: 8.rpx,
),
Expanded(
child: Container(
child: Text(
item.itemTitle,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(color: rgba(51, 51, 51, 1), fontSize: 12.rpx),
),
),
)
],
),
);
}
}
/// 价格信息
class _PriceInfo extends StatelessWidget {
final ShopSubItemList item;
_PriceInfo(this.item);
@override
Widget build(BuildContext context) {
return Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
children: [
Text(
"¥",
style: TextStyle(
color: rgba(255, 4, 0, 1),
fontSize: 11.rpx,
),
),
Text(
item.endPrice,
style: TextStyle(
color: rgba(255, 4, 0, 1),
fontSize: 14.rpx,
),
),
SizedBox(
width: 8.rpx,
),
Text(
${item.originalPrice}",
style: TextStyle(
color: rgba(153, 153, 153, 1),
fontSize: 12.rpx,
decoration: TextDecoration.lineThrough),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import './shop_item.dart';
import './goods_item.dart';
import '../models/shop_list_model.dart';
import 'package:mvp/mvp.dart';
import 'package:life_repository/life_repository.dart';
import 'package:common_module/utils/list_model_status_utils.dart';
import 'package:common_module/utils/xapp_utils.dart';
class ShopList extends StatelessWidget {
final ShopListModel model;
final Function(ShopItemEntity) onTap;
final Function() onReset;
ShopList({this.model, this.onTap, this.onReset});
@override
Widget build(BuildContext context) {
return SliverPadding(
padding: EdgeInsets.zero,
sliver: QMProvider<ShopListModel>.value(
model: model,
builderWidget: (context, model, child) {
Widget statusWidget = ListModelStatusUtils.getInstance().form(
failText: "没有搜到结果~",
btnText: "恢复默认",
paddingTop: 30.rpx,
iconSize: 200.rpx,
btnRadius: 40.rpx,
btnColor: Colors.black,
icon: "assets/life_img_no_location.png",
model: model,
onTap: onReset);
if (statusWidget != null) {
return SliverFillViewport(
delegate: SliverChildBuilderDelegate((context, index) {
return Container(
alignment: Alignment.topCenter,
child: statusWidget,
);
}, childCount: 1),
viewportFraction: 1.0,
);
}
return SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
var item = model.getList()[index];
if (item.type == 0) {
return ShopItem(
item: item.restaurant,
onTap: () {
onTap(item);
},
);
}
return GoodsItem(
item: item.combo,
onTap: () {
onTap(item);
},
);
},
childCount: model.getList().length,
));
},
),
);
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:navigation_bar/navigation_bar.dart';
import 'package:life_module/models/filter_model.dart';
import 'package:mvp/mvp.dart';
class ShopTypeNav extends StatelessWidget {
final FilterModel model;
final Function() onChange;
ShopTypeNav({this.model, this.onChange});
@override
Widget build(BuildContext context) {
return QMProvider<FilterModel>.value(
model: model,
builderWidget: (context, model, child) {
if (model.isEmpty()) {
return Container(
height: 37.rpx,
);
}
return Container(
height: 37.rpx,
alignment: Alignment.topLeft,
padding: EdgeInsets.only(top: 12.rpx),
color: rgba(245, 245, 245, 1),
child: DefaultTabController(
length: 2,
initialIndex: model.getShopTypeNavIndex(),
child: NavigationBar(
items: ["优惠店铺", "优惠套餐"],
selectColor: rgba(48, 38, 0, 1),
normalColor: rgba(48, 38, 0, 1),
selectStyle: TextStyle(
fontWeight: FontWeight.bold, fontSize: 18.rpx, height: 1),
normalStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.rpx,
height: 1,
),
isScrollable: true,
indicatorSize: TabBarIndicatorSize.label,
indicator: RoundRectIndicator(
round: 3.rpx,
color: rgba(255, 61, 0, 1),
height: 3.rpx,
marginBottom: 6.rpx),
onChange: (index) {
model.setShopTypeNavIndex(index);
onChange();
},
),
),
);
},
);
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
/// 券和团icon
class TypeIcon extends StatelessWidget {
final int type;
TypeIcon({this.type = 1});
@override
Widget build(BuildContext context) {
String text = type == 1 ? '团' : '券';
List<Color> colors = type == 1
? [rgba(255, 125, 0, 1), rgba(250, 18, 14, 1)]
: [rgba(255, 201, 0, 1), rgba(255, 143, 0, 1)];
return Container(
height: 16.rpx,
width: 16.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.rpx),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: colors)),
child: Text(
text,
style: TextStyle(color: Colors.white, fontSize: 11.rpx, height: 1.rpx),
),
);
}
}
library life;
export './views/life/view.dart';
export './views/city/view.dart';
export './views/city/city.dart';
export './views/shop/view.dart';
export './views/sec_kill/view.dart';
export './views/search/view.dart';
import 'package:flutter/material.dart';
import 'package:mvp/mvp.dart';
import 'package:life_repository/life_repository.dart';
class FilterModel extends BaseModel {
List<FilterItemEntity> _regions = [];
List<FilterItemEntity> _categorys = [];
List<FilterItemEntity> _sorts = [];
FilterItemEntity _checkedOneRegion;
FilterItemEntity _checkedOneCategory;
FilterItemEntity _checkedOneSort;
FilterItemEntity _checkedTwoRegion;
FilterItemEntity _checkedTwoCategory;
FilterItemEntity _checkedTwoSort;
// 筛选区域选中的索引
int _filterAreaIndex = 0;
// 二级类目控制器
TabController _shopClassNavTabController;
int _shopTypeNavIndex = 0;
// 搜索关键词
String _keywords;
Future<void> getFilterList(String cid) async {
FilterObject object = await FilterArepository.get().getFilterList(cid);
_regions = object.regions;
_categorys = object.categorys;
_sorts = object.sorts;
if (_regions.length > 0) {
_checkedOneRegion = _regions[0];
if (_checkedOneRegion.subs.length > 0) {
_checkedTwoRegion = _checkedOneRegion.subs[0];
}
}
if (_categorys.length > 0) {
_checkedOneCategory = _categorys[0];
if (_checkedOneCategory.subs.length > 0) {
_checkedTwoCategory = _checkedOneCategory.subs[0];
_shopClassNavTabController = TabController(
length: _checkedOneCategory.subs.length, vsync: ScrollableState());
}
}
if (_sorts.length > 0) {
_checkedOneSort = _sorts[0];
if (_checkedOneSort.subs.length > 0) {
_checkedTwoSort = _checkedOneSort.subs[0];
}
}
notifyListeners();
}
bool isEmpty() {
return _regions.length == 0 || _categorys.length == 0 || _sorts.length == 0;
}
int getFilterAreaIndex() {
return _filterAreaIndex;
}
void stFilterAreaIndex(int index) {
_filterAreaIndex = index;
notifyListeners();
}
FilterItemEntity getCheckedOneRegion() {
return _checkedOneRegion;
}
void setCheckedRegion(FilterItemEntity r1, FilterItemEntity r2) {
_checkedOneRegion = r1;
_checkedTwoRegion = r2;
notifyListeners();
}
FilterItemEntity getCheckedOneCategory() {
return _checkedOneCategory;
}
void setCheckedCategory(FilterItemEntity c1, FilterItemEntity c2) {
var oldCheckedOneCategory = _checkedOneCategory;
_checkedOneCategory = c1;
_checkedTwoCategory = c2;
int index = 0;
if (c2 != null && c1.subs.length > 0) {
index = c1.subs.indexWhere((item) => item.id == c2.id);
}
if (c1 != oldCheckedOneCategory) {
int oIndex = 0;
// 解决初始化为0无法自动滚回初始位置问题
if (index == 0) {
oIndex = 1;
}
_shopClassNavTabController = TabController(
length: c1.subs.length,
initialIndex: oIndex,
vsync: ScrollableState());
notifyListeners();
Future.delayed(Duration(milliseconds: 300)).then((value) {
_shopClassNavTabController.animateTo(index);
});
} else {
_shopClassNavTabController.animateTo(index);
}
}
void resetShopClassNavController() {}
FilterItemEntity getCheckedOneSort() {
return _checkedOneSort;
}
void setCheckedSort(FilterItemEntity s1, FilterItemEntity s2) {
_checkedOneSort = s1;
_checkedTwoSort = s2;
notifyListeners();
}
FilterItemEntity getCheckedTwoRegion() {
if (_checkedTwoRegion == null) {
return FilterItemEntity(null, null, []);
}
return _checkedTwoRegion;
}
FilterItemEntity getCheckedTwoCategory() {
return _checkedTwoCategory;
}
FilterItemEntity getCheckedTwoSort() {
if (_checkedTwoSort == null) {
return FilterItemEntity(null, null, []);
}
return _checkedTwoSort;
}
List<FilterItemEntity> getRegions() {
return _regions;
}
List<FilterItemEntity> getCategorys() {
return _categorys;
}
List<FilterItemEntity> getSorts() {
return _sorts;
}
TabController getShopClassNavTabController() {
return _shopClassNavTabController;
}
int getShopTypeNavIndex() {
return _shopTypeNavIndex;
}
void setShopTypeNavIndex(int index) {
_shopTypeNavIndex = index;
}
String getKeywords() {
return _keywords;
}
void setKeywords(String s) {
_keywords = s;
}
void reset() {
if (_regions.length > 0) {
FilterItemEntity onwItem = _regions[0];
FilterItemEntity twoItem;
if (onwItem.subs != null && onwItem.subs.length > 0) {
twoItem = onwItem.subs[0];
} else {
twoItem = FilterItemEntity(null, null, []);
}
setCheckedRegion(onwItem, twoItem);
}
if (_categorys.length > 0) {
FilterItemEntity onwItem = _categorys[0];
FilterItemEntity twoItem;
if (onwItem.subs != null && onwItem.subs.length > 0) {
twoItem = onwItem.subs[0];
} else {
twoItem = FilterItemEntity(null, null, []);
}
setCheckedCategory(onwItem, twoItem);
}
if (_sorts.length > 0) {
FilterItemEntity onwItem = _sorts[0];
FilterItemEntity twoItem;
if (onwItem.subs != null && onwItem.subs.length > 0) {
twoItem = onwItem.subs[0];
} else {
twoItem = FilterItemEntity(null, null, []);
}
setCheckedSort(onwItem, twoItem);
}
}
}
import 'package:mvp/mvp.dart';
import 'package:life_repository/life_repository.dart';
class ShopListModel extends BaseListModel<ShopItemEntity> {
String _cityId;
String _lat;
String _lng;
String _firstCateId;
String _keywords = '';
String _secondCateId;
String _regionId;
String _sortType;
// 0 优惠店铺,1 优惠套餐
int _shopTypeNavIndex = 0;
@override
Future<List<ShopItemEntity>> request() {
return _find();
}
Future<List<ShopItemEntity>> _find() {
if (_shopTypeNavIndex == 0) {
return ShopListRepository.get().findRestaurantList(
_cityId,
_lat,
_lng,
getPage().toString(),
_firstCateId,
_keywords,
_secondCateId,
_regionId,
_sortType);
}
return ShopListRepository.get().findComboList(
_cityId,
_lat,
_lng,
getPage().toString(),
_firstCateId,
_keywords,
_secondCateId,
_regionId,
_sortType);
}
void setCityId(String cid) {
_cityId = cid;
}
void setLat(String lat) {
_lat = lat;
}
void setLng(String lng) {
_lng = lng;
}
void setFirstCateId(String firstCateId) {
_firstCateId = firstCateId;
}
String getKeywords() {
return _keywords;
}
void setKeywords(String keywords) {
_keywords = keywords;
}
void setSecondCateId(String secondCateId) {
_secondCateId = secondCateId;
}
void setRegionId(String regionId) {
_regionId = regionId;
}
void setSortType(String sortType) {
_sortType = sortType;
}
void setShopTypeNavIndex(int index) {
_shopTypeNavIndex = index;
}
}
import 'package:flutter/foundation.dart';
const String LIFE_LOCATION_PAGE = "life_location_page"; // 生活定位选择地址
const String LIFE_SHOP_PAGE = "l_ife_shop_page"; // 生活店铺
///
/// 路由路径枚举管理
///
enum RouteCityPath {
//LOCATION_PAGE, //定位页面
LOCATION_CITY_PAGE, //定位中城市选择页面
LIFE_SEARCH_PAGE, // 搜索页面
LIFE_SEC_KILL_PAGE // 秒杀
}
///
/// 路由管理的扩展
///
extension RoutePathExt on RouteCityPath {
String get name => describeEnum(this);
String path() {
return name.replaceAll("_", "/");
}
}
import 'package:common_module/utils/amap_utils.dart';
import 'package:life_repository/repository/amap_repository.dart';
class Res {
///
/// 历史定位缓存信息key值
///
static String historyLocation = '_history_locations';
///
/// 高德地图Key
///
static String aWebMapKey = '9897a29ccc4b396fc7dc560c50973fae';
static String aAndroidMapKey = '565eee69e48dbbfe1eb408da0fc31256';
static String aIOSMapKey = 'e492fb8617d0e93332fe980a934778b0';
///
/// 城市数据
///
static String chinaCityData = 'packages/life_module/assets/data/china.json';
///
/// 城市的历史定位信息
///
static String cityHistoryLocation = 'city/history/location';
static String icArrowGray =
'packages/price_module/assets/images/ic_arrow_gray.png';
static String icGpsOrg = 'packages/life_module/assets/images/ic_gps_org.png';
///
/// 转换定位数据
/// [entity] 当前获取到的定位数据
///
static Future<LocationEntity> convertLocation({LocationEntity entity,String location}) async{
dynamic idata = await AMapRepository.get().geocodeAddress(key: Res.aWebMapKey, location: location);
if(idata['status'] == '1' && idata['regeocode'] != null){
if(idata['regeocode'] != null){
idata = idata['regeocode'];
entity.address = idata['formatted_address'];
if(idata['addressComponent'] != null){
idata = idata['addressComponent'];
entity.city = idata['city'];
entity.aoiName = entity.address;
entity.poiName = entity.address;
}
}
}
return Future.value(entity);
}
}
import 'package:common_module/utils/store_utils.dart';
class SearchHistoryUtils {
static SearchHistoryUtils _instance;
static SearchHistoryUtils getInstance() {
if (_instance == null) {
_instance = new SearchHistoryUtils();
}
return _instance;
}
String key = "__SearchHistoryUtils__";
void push(String s) {
if (s == null || s.isEmpty) {
return;
}
var words = StoreUtils.getInstance().getForKey(
key: key,
defaultValue:[]
);
words = List<String>.from(words);
words.insert(0, s);
Set<String> uniWordes = words.toSet();
words = uniWordes.toList();
if (words.length > 20) {
words = words.sublist(0, 20);
}
StoreUtils.getInstance().setKV(key: key, value: words);
}
List<String> getWords() {
var words = StoreUtils.getInstance().getForKey(
key: key,
);
if (words == null) {
return [];
}
return List<String>.from(words);
}
void clear() {
StoreUtils.getInstance().setKV(key: key, value: []);
}
}
export 'package:common_module/utils/app_tap_config_utils.dart';
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:flutter_boost/boost_navigator.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:life_module/components/life_image.dart';
class BuyLoadingDialogUtils {
static BuyLoadingDialogUtils _instance;
static BuyLoadingDialogUtils getInstance() {
if (_instance == null) {
_instance = new BuyLoadingDialogUtils._();
}
return _instance;
}
BuyLoadingDialogUtils._();
LoadingDialog show() {
return LoadingDialog();
}
}
class LoadingDialog {
Route route;
LoadingDialog() {
route = _LoadingDialogRouter(_LoadingDialog());
BoostNavigator.instance.appState.topContainer.navigator.push(route);
}
void close() {
if (route != null && route.navigator != null) {
route.navigator.pop(route);
}
}
}
// loading widget
class _LoadingDialog extends Dialog {
const _LoadingDialog()
: super(
clipBehavior: Clip.none,
);
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Material(
type: MaterialType.transparency,
child: Center(
child: Container(
width: 120.rpx,
height: 120.rpx,
decoration: BoxDecoration(
color: rgba(0, 0, 0, 0.6),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 22.rpx, bottom: 10.rpx),
child: Container(
width: 30.rpx,
height: 30.rpx,
child: LifeImage(
name: "assets/images/shop/loading_icon.png",
width: 30.rpx,
height: 30.rpx,
),
),
),
Padding(
padding: EdgeInsets.only(left: 8.rpx, right: 8.rpx),
child: Container(
child: Text(
"吃喝玩乐前先来小熊领优惠",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 13.rpx,
height: 1.2.rpx),
overflow: TextOverflow.clip,
),
),
)
],
),
),
),
),
onWillPop: () async {
return false;
},
);
}
}
// loading路由
class _LoadingDialogRouter extends PageRouteBuilder {
final Widget page;
_LoadingDialogRouter(this.page)
: super(
opaque: false,
barrierColor: Color(0x00000001),
pageBuilder: (context, animation, secondaryAnimation) => page,
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
child,
);
}
import 'package:flutter/material.dart';
import 'package:life_module/components/filter_panel.dart';
import 'package:life_repository/life_repository.dart';
import 'package:life_module/models/filter_model.dart';
class FilterPanelUtils {
static OverlayEntry overlayEntry;
static show({
@required BuildContext context,
@required FilterModel model,
@required List<FilterItemEntity> items,
@required String oneCheckedId,
Function() onChange,
double topOffset,
String twoCheckedId,
Function() onClose,
Function(FilterItemEntity onwItem, FilterItemEntity twoItem) onConfirm,
}) {
close();
OverlayState overlayState = Overlay.of(context);
overlayEntry = new OverlayEntry(builder: (context) {
return FilterPanel(
model: model,
items: items,
topOffset: topOffset,
oneCheckedId: oneCheckedId,
twoCheckedId: twoCheckedId,
onClose: () {
close();
onClose();
},
onConfirm: (onwItem, twoItem) {
close();
onConfirm(onwItem, twoItem);
},
onChange:onChange,
);
});
overlayState.insert(overlayEntry);
}
static void close() {
if (overlayEntry != null) {
overlayEntry.remove();
overlayEntry = null;
}
}
}
This diff is collapsed.
import 'dart:convert';
import 'package:common_module/utils/navigate_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:life_module/util/resource.dart';
import 'package:life_module/views/city/components/index.dart';
import 'package:azlistview/azlistview.dart';
import 'entity/city_model.dart';
class CityPage extends StatefulWidget {
final Map<String, dynamic> param;
const CityPage({Key key, this.param}) : super(key: key);
@override
_CityPageState createState() => _CityPageState();
}
class _CityPageState extends State<CityPage> {
List<CityModel> citysList = List<CityModel>.empty(growable: true);
ValueNotifier<SearchCityInfo> listenable =
ValueNotifier<SearchCityInfo>(null);
String _currentCity = '';
@override
void initState() {
super.initState();
if (widget.param != null && widget.param['currentCity'] != null) {
_currentCity = widget.param['currentCity'] as String;
}
if (_currentCity.isNotEmpty) {
citysList.add(
CityModel(
type: 0,
name: '当前城市',
tagIndex: '0',
citys: [_currentCity],
),
);
}
citysList.add(
CityModel(
type: 1,
name: '热门城市',
tagIndex: '1',
citys: ['北京', '上海', '广州', '深圳', '杭州', '南京', '重庆', '郑州', '西安', '成都'],
),
);
SearchCityInfo cityInfo = SearchCityInfo(citys: citysList, isSearch: false);
listenable.value = cityInfo;
rootBundle.loadString(Res.chinaCityData).then((value) {
List list = json.decode(value);
list.forEach((v) {
citysList.add(CityModel.fromJson(v));
});
}).whenComplete(() {
_handleList(list: citysList);
});
}
void _handleList({@required List<CityModel> list}) {
if (list.isEmpty) return;
for (int i = 0, length = list.length; i < length; i++) {
CityModel model = list[i];
if (model.type == -1) {
String pinyin = model.namePinyin;
String tag = pinyin.substring(0, 1).toUpperCase();
list[i].namePinyin = pinyin;
if (RegExp('[A-Z]').hasMatch(tag)) {
list[i].tagIndex = tag;
} else {
list[i].tagIndex = '#';
}
}
}
// A-Z sort.
SuspensionUtil.sortListBySuspensionTag(list);
// show sus tag.
SuspensionUtil.setShowSuspensionStatus(citysList);
SearchCityInfo cityInfo = SearchCityInfo(citys: citysList, isSearch: false);
listenable.value = cityInfo;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFF5F5F5),
appBar: buildAppBar(title: '选择城市',onPressed:(){
NavigateUtils.pop(arguments:{});
}),
body: _buildBody(),
);
}
TextEditingController _controller = TextEditingController();
Widget _buildBody() {
return Column(
children: [
//搜索框
buildSearchWidget(
hintText: '请输入城市名称',
onCityTap: () {},
controller: _controller,
onChanged: onChangedText,
),
Expanded(
child: buildAzListViewWidget(
notifier: listenable,
onCityTap: (String city) {
NavigateUtils.pop(arguments: {'city': city});
},
reEnteTap: () {
_controller.clear();
onChangedText('');
},
),
flex: 1,
),
],
);
}
void onChangedText(String text) {
Iterable<CityModel> citys = citysList
.where((ele) => (ele.type == 0 || ele.name.indexOf(text) > -1));
listenable.value = SearchCityInfo(
isSearch: text.isNotEmpty,
citys: List<CityModel>.from(citys),
keywords: text,
);
}
@override
void dispose() {
listenable.dispose();
_controller.dispose();
super.dispose();
}
}
This diff is collapsed.
import 'package:azlistview/azlistview.dart';
import 'package:flutter/foundation.dart';
class SearchCityInfo {
List<CityModel> citys;
bool isSearch = false;
String keywords;
SearchCityInfo({
this.citys,
this.isSearch,
this.keywords = '',
});
}
///
/// type = 0 当前城市
/// type = 1 热门城市
///
class CityModel extends ISuspensionBean {
String name;
String tagIndex;
String namePinyin;
int type = -1;
List<String> citys;
CityModel({
@required this.name,
this.tagIndex,
this.namePinyin,
this.type = -1,
this.citys,
});
CityModel.fromJson(Map<String, dynamic> json)
: name = json['name'],
namePinyin = json['pinyin'];
@override
String getSuspensionTag() => tagIndex;
}
This diff is collapsed.
import 'package:common_module/utils/store_utils.dart';
import 'package:mvp/mvp.dart';
import '../models/model.dart';
import '../models/app_nav_model.dart';
import '../models/sec_kill_model.dart';
import '../models/mini_banner_model.dart';
import 'package:life_module/models/filter_model.dart';
import 'package:life_module/models/shop_list_model.dart';
import 'package:common_module/utils/loading_dialog_utils.dart';
class IAction extends BaseAction<Model> {
AppNavModel _appNavModel = AppNavModel();
SecKillModel _killModel = SecKillModel();
MiniBannerModel _miniBannerModel = MiniBannerModel();
FilterModel _filterModel = FilterModel();
ShopListModel _shopListModel = ShopListModel();
@override
void initState() {
_init();
}
void _init() async {
setModel(Model());
await getModel().findPermission();
initLocation();
await getAppNavModel().getAppNavList();
await getMiniBannerModel().getActivityConfigList();
}
void initLocation() async{
// 没有定位权限,用ip定位
bool isFirstLifeLocation = StoreUtils.getInstance().getForKey(key:'is_first_life_location2');
if(isFirstLifeLocation == null){
StoreUtils.getInstance().setKV(key:'is_first_life_location2', value: true);
await getModel().reqPermission();
initLocation();
}else if (!getModel().getHasPermission()) {
getModel().ipConfigAddress().then((value) => initData());
} else {
getModel().getLocation().then((value){
initData();
});
}
}
Future<void> initData() async {
await getModel().findCityId();
String cityId = getModel().getCityId();
print('===========> cityId:$cityId');
if (cityId != null && cityId.isNotEmpty) {
await getSecKillModel().findDisplay(cityId);
await getFilterModel().getFilterList(cityId);
refreshShopList();
}
}
Future<void> refreshShopList() async {
var loading = LoadingDialogUtils.getInstance().show();
Future.delayed(Duration(seconds: 2)).then((value) {
if (loading != null) {
loading.close();
}
});
try {
getShopListModel()
.setShopTypeNavIndex(getFilterModel().getShopTypeNavIndex());
getShopListModel().setCityId(getModel().getCityId());
getShopListModel().setLat(getModel().getLatitude());
getShopListModel().setLng(getModel().getLongitude());
getShopListModel()
.setFirstCateId(getFilterModel().getCheckedOneCategory().id);
getShopListModel()
.setSecondCateId(getFilterModel().getCheckedTwoCategory().id ?? "");
if (getFilterModel().getCheckedTwoRegion().id == null) {
getShopListModel()
.setRegionId(getFilterModel().getCheckedOneRegion().id);
} else {
getShopListModel()
.setRegionId(getFilterModel().getCheckedTwoRegion().id);
}
getShopListModel().setSortType(getFilterModel().getCheckedOneSort().id);
getShopListModel().clear();
getShopListModel().scrollTop();
await getShopListModel().refresh();
} catch (e) {}
if (loading != null) {
loading.close();
}
}
void refresh() async {
String cityId = getModel().getCityId();
try {
await getAppNavModel().getAppNavList();
await getMiniBannerModel().getActivityConfigList();
} catch (e) {}
if (cityId != null && cityId.isNotEmpty) {
try {
await getSecKillModel().findDisplay(cityId);
} catch (e) {}
await getShopListModel().refresh();
}
}
AppNavModel getAppNavModel() {
return _appNavModel;
}
SecKillModel getSecKillModel() {
return _killModel;
}
MiniBannerModel getMiniBannerModel() {
return _miniBannerModel;
}
FilterModel getFilterModel() {
return _filterModel;
}
ShopListModel getShopListModel() {
return _shopListModel;
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import '../actions/action.dart';
import 'package:mvp/providers/provider.dart';
import '../models/app_nav_model.dart';
import 'package:life_repository/entity/app_nav_entity.dart';
import 'package:common_module/widget/xiaoxiong_base_image_widget/widget.dart';
import 'package:life_module/utils/activity_config_tap_utils.dart';
/// 钻石位
class DiamondBit extends StatelessWidget {
final IAction iAction;
final ValueNotifier<double> scrollIndex = ValueNotifier(0.0);
DiamondBit({Key key, this.iAction}) : super(key: key);
@override
Widget build(BuildContext context) {
return SliverToBoxAdapter(
child: QMProvider<AppNavModel>.value(
model: iAction.getAppNavModel(),
builderWidget: (context, model, child) {
if (model.getList().length == 0) {
return SizedBox();
}
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
NotificationListener(
onNotification: (ScrollNotification notification) {
double extentBefore = notification.metrics.extentBefore;
double extentAfter = notification.metrics.extentAfter;
double width = extentAfter + extentBefore;
scrollIndex.value = (extentBefore / width) * 10.rpx;
return true;
},
child: _DiamondGrid(model.getList()),
),
ValueListenableBuilder<double>(
valueListenable: scrollIndex,
builder:
(BuildContext context, dynamic value, Widget child) {
return _DiamondBitWidgetPagination(
offset: value, itemCount: model.getList().length);
},
),
]),
);
}),
);
}
}
/// 宫格
class _DiamondGrid extends StatelessWidget {
final List<AppNavEntity> items;
_DiamondGrid(this.items);
@override
Widget build(BuildContext context) {
int itemCount = items.length;
bool isOneRow = itemCount < 10;
bool isFull = itemCount == 10 || itemCount == 5;
return Theme(
data: ThemeData(platform: TargetPlatform.macOS),
child: Container(
height: (isOneRow ? 78.rpx : 156.rpx) + (isFull ? 20.rpx : 0),
padding: EdgeInsets.only(top: 8.rpx, bottom: isFull ? 20.rpx : 0),
child: GridView.builder(
scrollDirection: Axis.horizontal,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isOneRow ? 1 : 2,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
childAspectRatio: .95,
),
itemBuilder: (context, index) {
var item = items[index];
return InkWell(
onTap: () {
AppTapConfigUtils.getInstance().activityConfigTap(item.toJson());
},
child: Container(
alignment: Alignment.topCenter,
child: Column(
children: <Widget>[
SizedBox(
height: 8.rpx,
),
Container(
width: 40.rpx,
height: 40.rpx,
child: XiaoxiongBaseImageWidget(
imageUrl: item.iconUrl,
width: 40.rpx,
height: 40.rpx,
fit: BoxFit.cover,
),
),
SizedBox(
height: 2.rpx,
),
Text(
item.name,
overflow: TextOverflow.ellipsis,
style: TextStyle(
height: 1.3846153846153,
fontSize: 12.rpx,
color: rgba(48, 38, 0, 1)),
)
],
),
),
);
},
itemCount: items.length,
),
),
);
}
}
/// 指示器
class _DiamondBitWidgetPagination extends StatelessWidget {
final double offset;
final int itemCount;
_DiamondBitWidgetPagination({Key key, this.offset, this.itemCount})
: super(key: key);
@override
Widget build(BuildContext context) {
if (itemCount == 10 || itemCount <= 5) {
return SizedBox();
}
return Container(
width: double.infinity,
alignment: Alignment.center,
padding: EdgeInsets.only(bottom: 9.rpx, top: 4.rpx),
child: Container(
width: 20.rpx,
height: 3.rpx,
decoration: BoxDecoration(
color: Color(0xFFE9E9E9),
borderRadius: BorderRadius.all(Radius.circular(2.rpx))),
child: Stack(
children: [
Positioned(
left: offset,
child: Container(
width: 10.rpx,
height: 3.rpx,
decoration: BoxDecoration(
color: Color(0XFFFF8000),
borderRadius:
BorderRadius.all(Radius.circular(2.rpx)),
)))
],
)));
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import '../models/mini_banner_model.dart';
import 'package:mvp/mvp.dart';
import 'package:common_module/widget/xiaoxiong_base_image_widget/widget.dart';
import 'package:life_module/utils/activity_config_tap_utils.dart';
// assets/close_btn_black.png
class FloatBanner extends StatelessWidget {
final MiniBannerModel model;
FloatBanner({this.model});
@override
Widget build(BuildContext context) {
return QMProvider<MiniBannerModel>.value(
model: model,
builderWidget: (context, model, child) {
if (model.getFloatBannerEntity() == null) {
return SizedBox();
}
return Container(
height: 96.rpx,
width: 96.rpx,
child: Stack(
alignment: Alignment.topRight,
children: [
Positioned(
right: 0,
top: 10.rpx,
child: InkWell(
onTap: () {
AppTapConfigUtils.getInstance().activityConfigTap(model.getFloatBannerEntity().toJson());
model.removeFloatBannerEntity(true);
},
child: Container(
height: 76.rpx,
width: 76.rpx,
//padding: EdgeInsets.symmetric(horizontal: 9.rpx),
margin: EdgeInsets.only(top: 6.rpx, bottom: 6.rpx),
child: XiaoxiongBaseImageWidget(
imageUrl: model.getFloatBannerEntity().imgUrl,
height: 76.rpx,
fit: BoxFit.contain,
placeholder:(BuildContext context, String data){
return Container();
},
),
))),
InkWell(
onTap: () {
model.removeFloatBannerEntity();
},
child: Container(
height: 16.rpx,
alignment: Alignment.topRight,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.rpx),
),
child: Image.asset(
"assets/close_btn_black.png",
width: 16.rpx,
height: 16.rpx,
)),
)
],
),
);
},
);
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import '../models/mini_banner_model.dart';
import 'package:mvp/mvp.dart';
import 'package:common_module/widget/xiaoxiong_base_image_widget/widget.dart';
import 'package:life_module/utils/activity_config_tap_utils.dart';
class MiniBanner extends StatelessWidget {
final MiniBannerModel model;
MiniBanner({this.model});
@override
Widget build(BuildContext context) {
return SliverToBoxAdapter(
child: QMProvider<MiniBannerModel>.value(
model: model,
builderWidget: (context, model, child) {
if (model.getList().length == 0) {
return SizedBox();
}
// ;
List<Widget> items = model.getList().map((e) {
return Expanded(
child: InkWell(
onTap: () {
AppTapConfigUtils.getInstance().activityConfigTap(e.toJson());
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 4.rpx),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.rpx),
child: Container(
height: 50.rpx,
child: XiaoxiongBaseImageWidget(
imageUrl: e.imgUrl,
height: 50.rpx,
fit: BoxFit.cover,
),
)),
),
),
);
}).toList();
return Container(
height: 56.rpx,
padding: EdgeInsets.symmetric(horizontal: 9.rpx),
margin: EdgeInsets.only(top: 8.rpx, bottom: 6.rpx),
child: Row(
children: items,
),
);
},
),
);
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:life_module/components/shop_type_nav.dart';
import './diamond_bit.dart';
import './sec_kill.dart';
import './mini_banner.dart';
import 'package:life_module/components/filter_area.dart';
import 'package:life_module/components/shop_class_nav.dart';
import 'package:life_module/components/shop_list.dart';
import 'package:life_module/components/persistent_header_delegate.dart';
import '../actions/action.dart';
import 'package:flutter/rendering.dart';
import 'package:common_module/widget/pull_widget/widget.dart';
import 'package:common_module/utils/navigate_utils.dart';
import 'package:life_module/route/index.dart';
class ScrollBody extends StatefulWidget {
final IAction iAction;
final String isAuditMode;
final Function(double offset) onScroll;
final ScrollController controller;
ScrollBody({this.onScroll, this.iAction, this.controller,this.isAuditMode});
@override
State<StatefulWidget> createState() => _ScrollBodyState();
}
class _ScrollBodyState extends State<ScrollBody> {
ScrollController get controller => widget.controller;
void initState() {
super.initState();
controller.addListener(() {
widget.onScroll(controller.offset);
});
}
@override
Widget build(BuildContext context) {
return PullWidget(
headerInsertIndex: 1,
controller: widget.iAction.getShopListModel().getRefreshController(),
onLoad: () {
widget.iAction.getShopListModel().getData();
},
onRefresh: () {
widget.iAction.getShopListModel().refresh();
},
child: CustomScrollView(
controller: controller,
slivers: [
SliverAppBar(
backgroundColor: Colors.transparent,
toolbarHeight: 44.rpx,
),
DiamondBit(
iAction: widget.iAction,
),
SecKill(
iAction: widget.iAction,
),
MiniBanner(
model: widget.iAction.getMiniBannerModel(),
),
SliverPersistentHeader(
pinned: false,
delegate: PersistentHeaderDelegate(
minHeight: 37.rpx,
maxHeight: 37.rpx,
child: ShopTypeNav(
model: widget.iAction.getFilterModel(),
onChange: () {
widget.iAction.refreshShopList();
},
))),
SliverPersistentHeader(
pinned: true,
delegate: PersistentHeaderDelegate(
minHeight: 48.rpx,
maxHeight: 48.rpx,
child: FilterArea(
topOffset: 81.rpx - 37.rpx,
model: widget.iAction.getFilterModel(),
onTap: (c) {
var _context =
widget.iAction.getShopListModel().getContext();
RenderSliver renderSliver = _context
.findAncestorRenderObjectOfType<RenderSliver>();
if (renderSliver != null &&
renderSliver.constraints.overlap <= 0) {
Scrollable.ensureVisible(_context);
}
},
onChange: () {
widget.iAction.refreshShopList();
},
))),
SliverPersistentHeader(
pinned: true,
delegate: PersistentHeaderDelegate(
minHeight: 40.rpx,
maxHeight: 40.rpx,
child: ShopClassNav(
model: widget.iAction.getFilterModel(),
onChange: () {
widget.iAction.refreshShopList();
},
))),
ShopList(
model: widget.iAction.getShopListModel(),
onReset: () {
widget.iAction.getFilterModel().reset();
widget.iAction.refreshShopList();
},
onTap: (item) {
NavigateUtils.push(
path: LIFE_SHOP_PAGE,
arguments: {
'isAuditMode':widget.isAuditMode,
'shopId': item.combo != null
? item.combo.shopId
: item.restaurant.shopId,
'lat': widget.iAction.getModel().getLatitude(),
'lng': widget.iAction.getModel().getLongitude(),
'firstCateId': widget.iAction
.getFilterModel()
.getCheckedOneCategory()
.id,
'itemId': item.combo != null ? item.combo.dealId : "",
"cityName": widget.iAction.getModel().getCity()
},
isNative: false,
);
},
)
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:life_module/components/search_bar.dart';
import 'package:life_module/components/life_image.dart';
import 'package:common_module/utils/navigate_utils.dart';
import 'package:life_module/route/index.dart';
import 'package:life_module/views/life/models/model.dart';
import 'package:mvp/mvp.dart';
import '../actions/action.dart';
import 'package:common_module/utils/map_utils.dart';
class SearchArea extends StatefulWidget {
final IAction iAction;
final ValueNotifier<double> scrollOffset;
SearchArea({this.scrollOffset, this.iAction});
@override
State<StatefulWidget> createState() => _SearchAreaState();
}
class _SearchAreaState extends State<SearchArea> {
@override
Widget build(BuildContext context) {
// 最大滚动范围
double maxOffset = 44.rpx;
// 离左侧最大距离
double maxLeft = 101.rpx;
return Container(
child: QMProvider<Model>.value(
model: widget.iAction.getModel(),
builderWidget: (context, model, child) {
return ValueListenableBuilder<double>(
valueListenable: widget.scrollOffset,
builder: (BuildContext context, dynamic offset, Widget child) {
double opacity = 1;
if (offset >= maxOffset) {
// 超出最大滚动范围
opacity = 0.0;
offset = maxOffset;
} else if (offset > 0) {
// 滚动范围>0
opacity = 1 - offset / maxOffset;
} else if (offset < 0) {
// 滚动范围小于0
offset = 0.0;
}
double left = offset * (maxLeft / maxOffset) * 1.5;
if (left > maxLeft) {
left = maxLeft;
}
List<Widget> items = [
Opacity(
opacity: opacity,
child: _Locaion(
iAction: widget.iAction,
),
),
Positioned(
top: 44.rpx,
left: 0,
right: 0,
child: Container(
height: 44.rpx,
child: InkWell(
child: SearchBar(
enabled: false,
inputColor: rgba(245, 245, 245, 1),
),
onTap: () {
NavigateUtils.push(
path: RouteCityPath.LIFE_SEARCH_PAGE.path(),
arguments: {
'cityId': widget.iAction.getModel().getCityId(),
'latitude':
widget.iAction.getModel().getLatitude(),
'longitude':
widget.iAction.getModel().getLongitude(),
'cityName': widget.iAction.getModel().getCity(),
},
isNative: false,
);
},
),
margin: EdgeInsets.only(left: left),
padding: EdgeInsets.symmetric(
horizontal: 13.rpx, vertical: 5.rpx),
transform: Matrix4.translationValues(0, -offset, 0),
),
),
];
if (!model.getHasPermission()) {
items.add(Positioned(
top: 37.rpx,
right: 13.rpx,
child: opacity <= 0
? SizedBox()
: Opacity(
opacity: opacity,
child: _Bubble(widget.iAction),
),
));
}
return Container(
height: 88.rpx,
child: Stack(
children: items,
),
);
});
}),
);
}
}
/// 定位按钮
class _Locaion extends StatelessWidget {
final IAction iAction;
_Locaion({this.iAction});
@override
Widget build(BuildContext context) {
return QMProvider<Model>.value(
model: iAction.getModel(),
builderWidget: (context, model, child) {
return InkWell(
child: Container(
height: 44.rpx,
padding: EdgeInsets.only(right: 13.rpx),
alignment: Alignment.centerRight,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Image.asset('assets/ic_location.png',
width: 20.rpx, height: 20.rpx, fit: BoxFit.contain),
SizedBox(
width: 6.rpx,
),
Container(
constraints: BoxConstraints(maxWidth: 150.rpx),
child: Text(
model.getAddres(),
overflow: TextOverflow.clip,
maxLines: 1,
style: TextStyle(
color: rgba(48, 38, 0, 1),
fontSize: 13.rpx,
height: 1.1,
fontWeight: FontWeight.bold),
),
),
SizedBox(
width: 3.rpx,
),
Image.asset(
"assets/setup_enter.png",
height: 10.rpx,
color: rgba(48, 38, 0, 1),
width: 6.rpx,
fit: BoxFit.fitWidth,
),
SizedBox(
width: 7.rpx,
)
],
),
),
onTap: () async {
// 点击这里 返回不判断权限
model.setIsClickCitySelect(true);
var result = await NavigateUtils.push(
path: LIFE_LOCATION_PAGE,
arguments: {},
isNative: false,
);
if (result == null) {
return;
}
var location = result['location'].split(',');
var _latitude = '${location[1]}';
var _longitude = '${location[0]}';
List<num> arr = MapUtils.getInstance().gcj02ToGps84(
double.parse(_latitude), double.parse(_longitude));
_latitude = '${arr[0]}';
_longitude = '${arr[1]}';
model.setLocationInfo(result['cityname'] ?? result['city'],
result['name'], _latitude, _longitude);
await iAction.initData();
iAction.getModel().findPermission();
},
);
});
}
}
/// 气泡
class _Bubble extends StatelessWidget {
final IAction iAction;
_Bubble(this.iAction);
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
height: 38.rpx,
width: 200.rpx,
child: Column(
children: [
Container(
height: 8.rpx,
alignment: Alignment.topRight,
padding: EdgeInsets.only(right: 28.rpx, top: 2.5.rpx),
child: LifeImage(
name: "assets/images/life/ic_arrow_up.png",
color: rgba(0, 0, 0, 0.70),
width: 8.rpx,
height: 9.rpx,
fit: BoxFit.fitHeight,
),
),
Container(
height: 30.rpx,
decoration: BoxDecoration(
color: rgba(0, 0, 0, 0.70),
borderRadius: BorderRadius.circular(25.rpx),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () async {
await iAction.getModel().reqPermission();
if (iAction.getModel().getHasPermission()) {
iAction.initLocation();
}
},
child: Container(
height: 30.rpx,
padding: EdgeInsets.only(
left: 15.rpx,
),
alignment: Alignment.center,
child: Text(
"开启定位查看附近精准攻略",
style: TextStyle(
color: Colors.white,
fontSize: 12.rpx,
height: 1.2),
),
)),
InkWell(
child: Container(
height: 30.rpx,
padding: EdgeInsets.only(right: 10.rpx, left: 6.rpx),
child: Icon(
Icons.close,
color: Colors.white,
size: 15.rpx,
),
),
onTap: () {
iAction.getModel().setPermission();
},
)
],
),
)
],
));
}
}
This diff is collapsed.
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
import 'package:life_module/components/life_image.dart';
class TitleBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 44.rpx,
padding: EdgeInsets.only(left: 13.rpx),
alignment: Alignment.centerLeft,
child: LifeImage(
name: "assets/images/life/ic_local.png",
width: 80.rpx,
height: 20.rpx),
);
}
}
import 'package:mvp/mvp.dart';
import 'package:life_repository/life_repository.dart';
class AppNavModel extends BaseModel {
List<AppNavEntity> _list = [];
Future<void> getAppNavList() async {
_list = await AppNavRepository.get().getAppNavList("3");
notifyListeners();
}
List<AppNavEntity> getList() {
return _list;
}
}
import 'package:mvp/mvp.dart';
import 'package:life_repository/life_repository.dart';
import 'package:common_module/utils/store_utils.dart';
import 'package:common_module/utils/date_time_helper.dart';
const String _SHOP_KEY_ = "__life_float_banner__";
class MiniBannerModel extends BaseModel {
List<ActivityConfigEntity> _list = [];
ActivityConfigEntity floatBanner;
Future<void> getActivityConfigList() async {
_list = await AppNavRepository.get().getActivityConfigList("20");
List<ActivityConfigEntity> floats =
await AppNavRepository.get().getActivityConfigList("22");
if (floats.length > 0) {
floatBanner = floats[0];
}
notifyListeners();
}
List<ActivityConfigEntity> getList() {
return _list;
}
ActivityConfigEntity getFloatBannerEntity() {
if (floatBanner != null) {
String type = floatBanner.showType;
if (type != '2') {
String dateStr = StoreUtils.getInstance()
.getForKey(key: "$_SHOP_KEY_${floatBanner.id}");
if (type == '1' && dateStr != null) {
return null;
}
String nowDateStr =
DateUtil.formatDate(DateTime.now(), format: "yyyyMMdd");
if (type == '3' && dateStr == nowDateStr) {
return null;
}
}
}
return floatBanner;
}
void removeFloatBannerEntity([bool show = false]) {
if (floatBanner != null) {
String nowDateStr =
DateUtil.formatDate(DateTime.now(), format: "yyyyMMdd");
StoreUtils.getInstance()
.setKV(key: "$_SHOP_KEY_${floatBanner.id}", value: nowDateStr);
if (!show) {
floatBanner = null;
notifyListeners();
}
}
}
}
import 'package:common_module/utils/map_utils.dart';
import 'package:mvp/mvp.dart';
import 'package:life_repository/life_repository.dart';
import 'package:life_module/util/resource.dart';
import 'package:common_module/utils/amap_utils.dart';
import 'package:modal/modal.dart';
class Model extends BaseModel {
bool _hasPermission = false;
String _address = '';
String _city = '';
String _cityId = '';
String _latitude = '';
String _longitude = '';
bool _isClickCitySelect = false;
Future<void> findCityId() async {
_cityId = await CityRepository.get().getCityId(_city);
}
Future<void> getLocation() async {
LocationEntity location = await AmapUtils.getInstance().getLocation();
if((location?.address??'').isEmpty){
String myLocation = '${location.longitude},${location.latitude}';
location = await Res.convertLocation(entity:location,location:myLocation);
}
_latitude = location.latitude.toString();
_longitude = location.longitude.toString();
List<num> arr = MapUtils.getInstance()
.gcj02ToGps84(double.parse(_latitude), double.parse(_longitude));
_latitude = '${arr[0]}';
_longitude = '${arr[1]}';
_city = location.city;
_address = location.aoiName;
notifyListeners();
}
Future<void> ipConfigAddress() async {
var res = await AMapRepository.get().ipConfigAddress(key: Res.aWebMapKey);
List<String> rectangles = res.rectangle.split(new RegExp(r";|,"));
if (rectangles.length > 1) {
_latitude = rectangles[1];
_longitude = rectangles[0];
List<num> arr = MapUtils.getInstance()
.gcj02ToGps84(double.parse(_latitude), double.parse(_longitude));
_latitude = '${arr[0]}';
_longitude = '${arr[1]}';
}
_city = res.city;
_address = _city;
notifyListeners();
}
Future<void> findPermission() async {
_hasPermission = await AmapUtils.getInstance().hasPermission();
if (_hasPermission) {
_hasPermission = await AmapUtils.getInstance().isOpenGPS;
}
notifyListeners();
}
Future<void> reqPermission() async {
bool confirm = await Modal.showModal(
title: "温馨提示",
msg: "为给您提供更好的服务,需获取您的位置权限",
cancelBtnText: '拒绝',
confirmBtnText: '同意');
if (!confirm) {
return;
}
_hasPermission = await AmapUtils.getInstance().reqPermission();
if (_hasPermission) {
_hasPermission = await AmapUtils.getInstance().isOpenGPS;
if (!_hasPermission) {
confirm = await Modal.showModal(
title: "温馨提示",
msg: "为给您提供更好的服务,请打开GPS",
cancelBtnText: '拒绝',
confirmBtnText: '同意');
if (!confirm) {
return;
}
_hasPermission = await AmapUtils.getInstance().enableGPS();
}
}
notifyListeners();
}
void setPermission() {
_hasPermission = true;
notifyListeners();
}
bool getHasPermission() {
return _hasPermission;
}
void setLocationInfo(
String city, String address, String latitude, String longitude) {
_city = city;
_address = address;
_latitude = latitude;
_longitude = longitude;
notifyListeners();
}
String getAddres() {
return _address??'';
}
void setName(String name) {
this._address = name;
}
String getCityId() {
return _cityId;
}
String getCity() {
return _city;
}
String getLatitude() {
return _latitude;
}
String getLongitude() {
return _longitude;
}
bool isClickCitySelect() {
return _isClickCitySelect;
}
void setIsClickCitySelect(bool isc) {
_isClickCitySelect = isc;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
import 'package:mvp/mvp.dart';
import 'package:life_repository/life_repository.dart';
class BannerModel extends BaseModel {
List<ActivityConfigEntity> list = [];
Future<void> getActivityConfigList() async {
list = await AppNavRepository.get().getActivityConfigList("21");
notifyListeners();
}
List<ActivityConfigEntity> getList() {
return list;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
import 'package:flutter/material.dart';
import 'package:common_module/utils/xapp_utils.dart';
class ItemBar extends StatelessWidget {
final GlobalKey globalKey;
final String text;
ItemBar(this.globalKey, this.text);
@override
Widget build(BuildContext context) {
return SliverToBoxAdapter(
child: Container(
key: globalKey,
height: 34.rpx,
padding: EdgeInsets.only(top: 12.rpx, left: 12.rpx),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(8.rpx))),
child: Text(
text,
style: TextStyle(
color: rgba(48, 38, 0, 1),
fontSize: 15.rpx,
fontWeight: FontWeight.bold),
),
));
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment