@@ -112,9 +112,9 @@ android { | |||||
// 智夜生活 | // 智夜生活 | ||||
zhiying { | zhiying { | ||||
applicationId "cn.zhios.zhiying" | applicationId "cn.zhios.zhiying" | ||||
versionCode 32 | |||||
versionCode 33 | |||||
dimension "app" | dimension "app" | ||||
versionName '1.2.32' | |||||
versionName '1.2.33' | |||||
// 签名信息 | // 签名信息 | ||||
signingConfig signingConfigs.zhiying | signingConfig signingConfigs.zhiying | ||||
} | } | ||||
@@ -136,6 +136,7 @@ class __CustomItemPageContainerState extends State<_CustomItemPageContainer> wit | |||||
}, | }, | ||||
builder: (context, state) { | builder: (context, state) { | ||||
if (state is CustomItemPageLoadedState) { | if (state is CustomItemPageLoadedState) { | ||||
Logger.log('custom item page current state = ' + state?.toString()); | |||||
if (EmptyUtil.isEmpty(state.model)) | if (EmptyUtil.isEmpty(state.model)) | ||||
return _buildEmptyWidget(); | return _buildEmptyWidget(); | ||||
else | else | ||||
@@ -59,7 +59,7 @@ class _CommonPageContainer extends StatefulWidget { | |||||
__CommonPageContainerState createState() => __CommonPageContainerState(); | __CommonPageContainerState createState() => __CommonPageContainerState(); | ||||
} | } | ||||
class __CommonPageContainerState extends State<_CommonPageContainer> with SingleTickerProviderStateMixin { | |||||
class __CommonPageContainerState extends State<_CommonPageContainer> with SingleTickerProviderStateMixin ,AutomaticKeepAliveClientMixin{ | |||||
TabController _tabController; | TabController _tabController; | ||||
// 是否有AppBar | // 是否有AppBar | ||||
@@ -418,6 +418,10 @@ class __CommonPageContainerState extends State<_CommonPageContainer> with Single | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@override | |||||
// TODO: implement wantKeepAlive | |||||
bool get wantKeepAlive =>true; | |||||
} | } | ||||
/// 回到顶部的icon | /// 回到顶部的icon | ||||
@@ -336,4 +336,5 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver, Ticker | |||||
) | ) | ||||
])); | ])); | ||||
} | } | ||||
} | } |
@@ -110,6 +110,7 @@ class _MainPageContainerState extends State<_MainPageContainer> { | |||||
return StreamBuilder<List<Map<String, dynamic>>>( | return StreamBuilder<List<Map<String, dynamic>>>( | ||||
stream: _bloc.outData, | stream: _bloc.outData, | ||||
builder: (BuildContext context, AsyncSnapshot snapshot) { | builder: (BuildContext context, AsyncSnapshot snapshot) { | ||||
print("mainPageBuild"); | |||||
List widgets = _createContent(context, snapshot.data ?? []); | List widgets = _createContent(context, snapshot.data ?? []); | ||||
_refreshController.refreshCompleted(); | _refreshController.refreshCompleted(); | ||||
Widget bgWidget = validateBgWidget(context, snapshot.data ?? []); | Widget bgWidget = validateBgWidget(context, snapshot.data ?? []); | ||||
@@ -35,7 +35,7 @@ class OrderContentBloc extends BlocBase { | |||||
params['state'] = _state; | params['state'] = _state; | ||||
NetUtil.request('/api/v1/order', method: NetMethod.POST, params: params, | NetUtil.request('/api/v1/order', method: NetMethod.POST, params: params, | ||||
onCache: (data) { | onCache: (data) { | ||||
_parseData(data); | |||||
//_parseData(data); | |||||
}, onSuccess: (data) { | }, onSuccess: (data) { | ||||
_parseData(data); | _parseData(data); | ||||
}); | }); | ||||
@@ -66,6 +66,6 @@ class OrderContentBloc extends BlocBase { | |||||
return OrderModel.fromJson(Map<String, dynamic>.from(item)); | return OrderModel.fromJson(Map<String, dynamic>.from(item)); | ||||
}).toList()); | }).toList()); | ||||
_ordersController.add(_orders); | |||||
_ordersController?.add(_orders); | |||||
} | } | ||||
} | } |
@@ -22,7 +22,7 @@ class OrderPageBloc extends BlocBase { | |||||
void loadData(String skipIdentifier) async { | void loadData(String skipIdentifier) async { | ||||
NetUtil.request('/api/v1/mod/${skipIdentifier.toString()}', | NetUtil.request('/api/v1/mod/${skipIdentifier.toString()}', | ||||
method: NetMethod.GET, onCache: (data) { | method: NetMethod.GET, onCache: (data) { | ||||
_loadData(data); | |||||
// _loadData(data); | |||||
}, onSuccess: (data) { | }, onSuccess: (data) { | ||||
_loadData(data); | _loadData(data); | ||||
}); | }); | ||||
@@ -20,6 +20,8 @@ class OrderModel { | |||||
String confirmAt; | String confirmAt; | ||||
String settleAt; | String settleAt; | ||||
String thumbnail; | String thumbnail; | ||||
int priceType; | |||||
String priceName; | |||||
Map<String, dynamic> data; // 保存原始数据 | Map<String, dynamic> data; // 保存原始数据 | ||||
OrderModel({ | OrderModel({ | ||||
@@ -69,6 +71,8 @@ class OrderModel { | |||||
confirmAt = json['confirm_at']; | confirmAt = json['confirm_at']; | ||||
settleAt = json['settle_at']; | settleAt = json['settle_at']; | ||||
thumbnail = json['thumbnail']; | thumbnail = json['thumbnail']; | ||||
priceType=json['price_type']; | |||||
priceName=json['price_name']; | |||||
data = json; | data = json; | ||||
} | } | ||||
@@ -1,3 +1,5 @@ | |||||
import 'dart:async'; | |||||
import 'package:event_bus/event_bus.dart'; | import 'package:event_bus/event_bus.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:pull_to_refresh/pull_to_refresh.dart'; | import 'package:pull_to_refresh/pull_to_refresh.dart'; | ||||
@@ -59,13 +61,15 @@ class _OrderContentContainerState extends State<OrderContentContainer> { | |||||
OrderContentBloc _bloc; | OrderContentBloc _bloc; | ||||
RefreshController _refreshController = | RefreshController _refreshController = | ||||
RefreshController(initialRefresh: false); | RefreshController(initialRefresh: false); | ||||
StreamSubscription streamSubscription; | |||||
@override | @override | ||||
void initState() { | void initState() { | ||||
_bloc = BlocProvider.of(context); | _bloc = BlocProvider.of(context); | ||||
_bloc.refresh(widget.state, widget.filter); | _bloc.refresh(widget.state, widget.filter); | ||||
widget.eventBus.on<int>().listen((index) { | |||||
streamSubscription= widget.eventBus.on<int>().listen((index) { | |||||
print('eventbus' + index.toString()); | |||||
if (index == widget.index) { | if (index == widget.index) { | ||||
_bloc.refresh(widget.state, widget.filter); | _bloc.refresh(widget.state, widget.filter); | ||||
} | } | ||||
@@ -73,6 +77,11 @@ class _OrderContentContainerState extends State<OrderContentContainer> { | |||||
super.initState(); | super.initState(); | ||||
} | } | ||||
@override | |||||
void dispose() { | |||||
streamSubscription.cancel(); | |||||
super.dispose(); | |||||
} | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
@@ -1,3 +1,5 @@ | |||||
import 'dart:io'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:flutter/services.dart'; | import 'package:flutter/services.dart'; | ||||
import 'package:fluttertoast/fluttertoast.dart'; | import 'package:fluttertoast/fluttertoast.dart'; | ||||
@@ -18,8 +20,7 @@ class OrderItemWidget extends StatelessWidget { | |||||
margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 4, bottom: 4), | margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 4, bottom: 4), | ||||
padding: EdgeInsets.all(10), | padding: EdgeInsets.all(10), | ||||
width: double.infinity, | width: double.infinity, | ||||
decoration: BoxDecoration( | |||||
borderRadius: BorderRadius.circular(7.5), color: Colors.white), | |||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.5), color: Colors.white), | |||||
child: Column( | child: Column( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
_createHeader(), | _createHeader(), | ||||
@@ -48,21 +49,35 @@ class OrderItemWidget extends StatelessWidget { | |||||
} | } | ||||
List<OrderStateModel> states = style.list.orderState; | List<OrderStateModel> states = style.list.orderState; | ||||
OrderStateModel state = | |||||
states.firstWhere((element) => element.type == model.state.toString()); | |||||
OrderStateModel state = states.firstWhere((element) => element.type == model.state.toString()); | |||||
return Padding( | return Padding( | ||||
padding: const EdgeInsets.only(bottom: 8), | padding: const EdgeInsets.only(bottom: 8), | ||||
child: Row( | child: Row( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Expanded( | Expanded( | ||||
child: Text( | |||||
type ?? '', | |||||
maxLines: 1, | |||||
style: TextStyle( | |||||
fontSize: 12, | |||||
fontWeight: FontWeight.bold, | |||||
color: Color(0xff333333), | |||||
), | |||||
child: Row( | |||||
children: <Widget>[ | |||||
Text( | |||||
type ?? '', | |||||
maxLines: 1, | |||||
style: TextStyle( | |||||
fontSize: 12, | |||||
fontWeight: FontWeight.bold, | |||||
color: Color(0xff333333), | |||||
), | |||||
), | |||||
model?.priceName == null | |||||
? Container() | |||||
: Container( | |||||
decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(4)), | |||||
margin: EdgeInsets.only(left: 4), | |||||
padding: EdgeInsets.all(3), | |||||
child: Text( | |||||
model?.priceName ?? "", | |||||
style: TextStyle(color: HexColor.fromHex("#FFFFFF"), fontSize: 9, height: 1), | |||||
), | |||||
) | |||||
], | |||||
), | ), | ||||
), | ), | ||||
Text( | Text( | ||||
@@ -102,8 +117,7 @@ class OrderItemWidget extends StatelessWidget { | |||||
_createTitle(), | _createTitle(), | ||||
Row( | Row( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
_creteText( | |||||
'${style?.list?.textOrderNo ?? ''}${model?.ordId ?? ''}'), | |||||
_creteText('${style?.list?.textOrderNo ?? ''}${model?.ordId ?? ''}'), | |||||
GestureDetector( | GestureDetector( | ||||
onTap: () { | onTap: () { | ||||
if (model?.ordId != null && model.ordId.length > 0) { | if (model?.ordId != null && model.ordId.length > 0) { | ||||
@@ -132,10 +146,8 @@ class OrderItemWidget extends StatelessWidget { | |||||
) | ) | ||||
], | ], | ||||
), | ), | ||||
_creteText( | |||||
'${style?.list?.textOrderTime ?? ''}${model?.createAt ?? ''}'), | |||||
_creteText( | |||||
'${style?.list?.textFinishTime ?? ''}${model?.confirmAt ?? ''}'), | |||||
_creteText('${style?.list?.textOrderTime ?? ''}${model?.createAt ?? ''}'), | |||||
_creteText('${style?.list?.textFinishTime ?? ''}${model?.confirmAt ?? ''}'), | |||||
], | ], | ||||
), | ), | ||||
) | ) | ||||
@@ -147,10 +159,7 @@ class OrderItemWidget extends StatelessWidget { | |||||
List<InlineSpan> list = List(); | List<InlineSpan> list = List(); | ||||
String shop = ''; | String shop = ''; | ||||
if (model?.provider != null && model.provider != '') { | if (model?.provider != null && model.provider != '') { | ||||
shop = style.filter.providerType | |||||
.firstWhere((element) => element.type == model.provider) | |||||
?.name ?? | |||||
''; | |||||
shop = style.filter.providerType.firstWhere((element) => element.type == model.provider)?.name ?? ''; | |||||
} | } | ||||
if (shop != '') { | if (shop != '') { | ||||
list.add(WidgetSpan( | list.add(WidgetSpan( | ||||
@@ -162,23 +171,17 @@ class OrderItemWidget extends StatelessWidget { | |||||
style: TextStyle( | style: TextStyle( | ||||
fontSize: 9, | fontSize: 9, | ||||
height: 1, | height: 1, | ||||
color: | |||||
HexColor.fromHex(style.list.colorProviderFont ?? '#ffffff'), | |||||
color: HexColor.fromHex(style.list.colorProviderFont ?? '#ffffff'), | |||||
), | ), | ||||
), | ), | ||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex(style.list.colorProviderBg ?? '#ffffff'), | |||||
borderRadius: BorderRadius.circular(2.5)), | |||||
decoration: BoxDecoration(color: HexColor.fromHex(style.list.colorProviderBg ?? '#ffffff'), borderRadius: BorderRadius.circular(2.5)), | |||||
), | ), | ||||
)); | )); | ||||
} | } | ||||
list.add( | list.add( | ||||
TextSpan( | TextSpan( | ||||
text: model?.itemTitle ?? '', | text: model?.itemTitle ?? '', | ||||
style: TextStyle( | |||||
fontSize: 15, | |||||
color: Color(0xff333333), | |||||
fontWeight: FontWeight.bold), | |||||
style: TextStyle(fontSize: 15, color: Color(0xff333333), fontWeight: FontWeight.bold), | |||||
), | ), | ||||
); | ); | ||||
return RichText( | return RichText( | ||||
@@ -205,8 +208,7 @@ class OrderItemWidget extends StatelessWidget { | |||||
Widget _createTips() { | Widget _createTips() { | ||||
List<OrderStateModel> states = style.list.orderState; | List<OrderStateModel> states = style.list.orderState; | ||||
OrderStateModel state = | |||||
states.firstWhere((element) => element.type == model.state.toString()); | |||||
OrderStateModel state = states.firstWhere((element) => element.type == model.state.toString()); | |||||
if (state == null || state.tips == null || state.tips == '') { | if (state == null || state.tips == null || state.tips == '') { | ||||
return Container(); | return Container(); | ||||
} | } | ||||
@@ -214,9 +216,7 @@ class OrderItemWidget extends StatelessWidget { | |||||
margin: EdgeInsets.only(top: 8), | margin: EdgeInsets.only(top: 8), | ||||
padding: EdgeInsets.only(left: 8, right: 8, top: 2, bottom: 2), | padding: EdgeInsets.only(left: 8, right: 8, top: 2, bottom: 2), | ||||
width: double.infinity, | width: double.infinity, | ||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex(style.list.colorTipsBg ?? '#f5f5f5'), | |||||
borderRadius: BorderRadius.circular(4)), | |||||
decoration: BoxDecoration(color: HexColor.fromHex(style.list.colorTipsBg ?? '#f5f5f5'), borderRadius: BorderRadius.circular(4)), | |||||
child: Text( | child: Text( | ||||
state?.tips ?? '', | state?.tips ?? '', | ||||
style: TextStyle(color: Color(0xff666666), fontSize: 10), | style: TextStyle(color: Color(0xff666666), fontSize: 10), | ||||
@@ -77,7 +77,6 @@ class _SearchPageContianerState extends State<SearchPageContianer> { | |||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
//设置搜索bar应该选择哪个type的item | //设置搜索bar应该选择哪个type的item | ||||
Logger.log("数据2: " + json.encode(widget.data)); | Logger.log("数据2: " + json.encode(widget.data)); | ||||
Logger.log("类型: " + widget.data['default_pvd']); | |||||
if(!EmptyUtil.isEmpty(widget.data['default_pvd'])){ | if(!EmptyUtil.isEmpty(widget.data['default_pvd'])){ | ||||
Provider.of<SearchTagNotifier>(context, listen: false).setType(widget.data['default_pvd']); | Provider.of<SearchTagNotifier>(context, listen: false).setType(widget.data['default_pvd']); | ||||
} | } | ||||
@@ -1,3 +1,4 @@ | |||||
import 'dart:async'; | |||||
import 'dart:math'; | import 'dart:math'; | ||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
@@ -5,6 +6,7 @@ import 'package:flutter/material.dart'; | |||||
import 'package:flutter_bloc/flutter_bloc.dart'; | import 'package:flutter_bloc/flutter_bloc.dart'; | ||||
import 'package:flutter_swiper/flutter_swiper.dart'; | import 'package:flutter_swiper/flutter_swiper.dart'; | ||||
import 'package:tab_indicator_styler/tab_indicator_styler.dart'; | import 'package:tab_indicator_styler/tab_indicator_styler.dart'; | ||||
import 'package:zhiying_base_widget/widgets/primary_page_view/primary_page_view.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
import 'package:cached_network_image/cached_network_image.dart'; | import 'package:cached_network_image/cached_network_image.dart'; | ||||
import 'custom_quick_entry_sk.dart'; | import 'custom_quick_entry_sk.dart'; | ||||
@@ -19,9 +21,9 @@ class CustomQuickEntry extends StatelessWidget { | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return BlocProvider<CustomQuickEntryBloc>( | return BlocProvider<CustomQuickEntryBloc>( | ||||
create: (_) => | |||||
CustomQuickEntryBloc(repository: CustomQuickEntryRepository()) | |||||
..add(CustomQuickEntryInitEvent(model: model)), | |||||
create: (_) { | |||||
return CustomQuickEntryBloc(repository: CustomQuickEntryRepository())..add(CustomQuickEntryInitEvent(model: model)); | |||||
}, | |||||
child: _CustomQuickEntryContainer(model), | child: _CustomQuickEntryContainer(model), | ||||
); | ); | ||||
} | } | ||||
@@ -30,13 +32,13 @@ class CustomQuickEntry extends StatelessWidget { | |||||
class _CustomQuickEntryContainer extends StatefulWidget { | class _CustomQuickEntryContainer extends StatefulWidget { | ||||
final Map<String, dynamic> model; | final Map<String, dynamic> model; | ||||
_CustomQuickEntryContainer(this.model); | |||||
_CustomQuickEntryContainer(this.model, {Key key}) : super(key: key); | |||||
@override | @override | ||||
__CustomQuickEntryContainerState createState() => __CustomQuickEntryContainerState(); | __CustomQuickEntryContainerState createState() => __CustomQuickEntryContainerState(); | ||||
} | } | ||||
class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> { | |||||
class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> with TickerProviderStateMixin, AutomaticKeepAliveClientMixin { | |||||
/// Icon点击事件 | /// Icon点击事件 | ||||
void _itemIconClick(ListStyle model) { | void _itemIconClick(ListStyle model) { | ||||
print("item type = ${model.skipIdentifier}"); | print("item type = ${model.skipIdentifier}"); | ||||
@@ -49,12 +51,14 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
@override | @override | ||||
void initState() { | void initState() { | ||||
_controller = SwiperController(); | _controller = SwiperController(); | ||||
super.initState(); | super.initState(); | ||||
} | } | ||||
@override | @override | ||||
void dispose() { | void dispose() { | ||||
_controller?.dispose(); | _controller?.dispose(); | ||||
super.dispose(); | super.dispose(); | ||||
} | } | ||||
@@ -63,14 +67,24 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
return BlocConsumer<CustomQuickEntryBloc, CustomQuickEntryState>( | return BlocConsumer<CustomQuickEntryBloc, CustomQuickEntryState>( | ||||
listener: (context, state) {}, | listener: (context, state) {}, | ||||
buildWhen: (prev, current) { | buildWhen: (prev, current) { | ||||
if (prev is CustomQuickEntryLoadedState) { | |||||
return false; | |||||
} | |||||
return true; | return true; | ||||
}, | }, | ||||
builder: (context, state) { | builder: (context, state) { | ||||
print("构建"); | |||||
if (state is CustomQuickEntryCachedState) { | if (state is CustomQuickEntryCachedState) { | ||||
return _getMainWidget(state.model); | return _getMainWidget(state.model); | ||||
} | } | ||||
if (state is CustomQuickEntryLoadedState) { | if (state is CustomQuickEntryLoadedState) { | ||||
return _getMainWidget(state.model); | |||||
if (state.model.isShowCategory == "1") { | |||||
return CustomQuickCateEntry( | |||||
model: state.model, | |||||
); | |||||
} else { | |||||
return _getMainWidget(state.model); | |||||
} | |||||
} | } | ||||
if (state is CustomQuickEntryErrorState) { | if (state is CustomQuickEntryErrorState) { | ||||
return Container(); | return Container(); | ||||
@@ -91,15 +105,15 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
int columSize = int.parse(model?.columSize ?? '5'); | int columSize = int.parse(model?.columSize ?? '5'); | ||||
//计算实际显示行数 | //计算实际显示行数 | ||||
if(totalRowSize*columSize>totalDataSize){ | |||||
for(int index=1;index<=totalRowSize;index++){ | |||||
if(index*columSize>=totalDataSize){ | |||||
totalRowSize=index; | |||||
if (totalRowSize * columSize > totalDataSize) { | |||||
for (int index = 1; index <= totalRowSize; index++) { | |||||
if (index * columSize >= totalDataSize) { | |||||
totalRowSize = index; | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
print("行数"+totalRowSize.toString()); | |||||
print("行数" + totalRowSize.toString()); | |||||
// 图标的高度 | // 图标的高度 | ||||
double iconHeight = 40.0; | double iconHeight = 40.0; | ||||
@@ -128,7 +142,7 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
// 总体高度 = 行数 * (子元素高度 + 边距高度) + 进度条的高度 | // 总体高度 = 行数 * (子元素高度 + 边距高度) + 进度条的高度 | ||||
double totalHeight = totalRowSize * (itemHeight + barMargin); | double totalHeight = totalRowSize * (itemHeight + barMargin); | ||||
if (totalPage > 1 && !EmptyUtil.isEmpty(model?.pagination) && model.pagination != 'type_null' /*model.pagination_open == '0'*/) { | if (totalPage > 1 && !EmptyUtil.isEmpty(model?.pagination) && model.pagination != 'type_null' /*model.pagination_open == '0'*/) { | ||||
totalHeight = totalRowSize * (itemHeight + barMargin); | |||||
totalHeight = totalRowSize * (itemHeight + barMargin)+8; | |||||
} | } | ||||
// 分类导航高度 | // 分类导航高度 | ||||
@@ -150,10 +164,7 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
double marginLeftRight = model?.isLeftRightMargin == "1" ? double.tryParse(model?.leftRightMargin ?? "0") : 0; | double marginLeftRight = model?.isLeftRightMargin == "1" ? double.tryParse(model?.leftRightMargin ?? "0") : 0; | ||||
double marginTop = model?.isTopMargin == "1" ? double.tryParse(model?.topMargin ?? "0") : 0; | double marginTop = model?.isTopMargin == "1" ? double.tryParse(model?.topMargin ?? "0") : 0; | ||||
return Container( | return Container( | ||||
margin: EdgeInsets.only(top: marginTop, | |||||
left: marginLeftRight, | |||||
right: marginLeftRight), | |||||
margin: EdgeInsets.only(top: marginTop, left: marginLeftRight, right: marginLeftRight), | |||||
decoration: BoxDecoration( | decoration: BoxDecoration( | ||||
color: HexColor.fromHex(model?.bgColor ?? ''), | color: HexColor.fromHex(model?.bgColor ?? ''), | ||||
//color: Colors.green, | //color: Colors.green, | ||||
@@ -162,10 +173,9 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
topLeft: Radius.circular(ParseUtil.stringParseDouble(model?.topLeftRadius)), | topLeft: Radius.circular(ParseUtil.stringParseDouble(model?.topLeftRadius)), | ||||
bottomLeft: Radius.circular(ParseUtil.stringParseDouble(model?.bottomLeftRadius)), | bottomLeft: Radius.circular(ParseUtil.stringParseDouble(model?.bottomLeftRadius)), | ||||
bottomRight: Radius.circular(ParseUtil.stringParseDouble(model?.bottomRightRadius)), | bottomRight: Radius.circular(ParseUtil.stringParseDouble(model?.bottomRightRadius)), | ||||
) | |||||
), | |||||
)), | |||||
child: Container( | child: Container( | ||||
margin: EdgeInsets.only(top: !hasCategory ? 15 : 0, bottom: totalPage > 1 ? 15 : 0), | |||||
margin: EdgeInsets.only(top: !hasCategory ? 15 : 0, bottom: totalPage > 1 ? 8 : 0), | |||||
height: totalHeight, | height: totalHeight, | ||||
// 总体高度 | // 总体高度 | ||||
width: double.infinity, | width: double.infinity, | ||||
@@ -173,12 +183,11 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
child: Column( | child: Column( | ||||
crossAxisAlignment: CrossAxisAlignment.start, | crossAxisAlignment: CrossAxisAlignment.start, | ||||
children: <Widget>[ | children: <Widget>[ | ||||
// 左上角标题 | // 左上角标题 | ||||
Visibility( | Visibility( | ||||
visible: !EmptyUtil.isEmpty(model?.moduleTitleName), | visible: !EmptyUtil.isEmpty(model?.moduleTitleName), | ||||
child: Padding( | child: Padding( | ||||
padding: const EdgeInsets.only(left: 12.5, bottom: 10), | |||||
padding: const EdgeInsets.only(left: 12.5, bottom: 10), | |||||
child: Text(model?.moduleTitleName ?? '', style: TextStyle(color: HexColor.fromHex(model?.moduleTitleColor), fontWeight: FontWeight.bold, fontSize: 15))), | child: Text(model?.moduleTitleName ?? '', style: TextStyle(color: HexColor.fromHex(model?.moduleTitleColor), fontWeight: FontWeight.bold, fontSize: 15))), | ||||
), | ), | ||||
@@ -272,7 +281,6 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
// )), | // )), | ||||
// ), | // ), | ||||
// ) | // ) | ||||
], | ], | ||||
), | ), | ||||
), | ), | ||||
@@ -311,16 +319,17 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
} | } | ||||
/// 行的数据 | /// 行的数据 | ||||
Widget _getRowWidget({double titleHeight, | |||||
double iconHeight, | |||||
int totalPage, | |||||
int currentPage, | |||||
int columSize, | |||||
int totalRowSize, | |||||
int totalDataSize, | |||||
CustomQuickEntryModel model, | |||||
int currentRow, | |||||
double itemHeight}) { | |||||
Widget _getRowWidget( | |||||
{double titleHeight, | |||||
double iconHeight, | |||||
int totalPage, | |||||
int currentPage, | |||||
int columSize, | |||||
int totalRowSize, | |||||
int totalDataSize, | |||||
CustomQuickEntryModel model, | |||||
int currentRow, | |||||
double itemHeight}) { | |||||
List itemList = []; | List itemList = []; | ||||
for (int i = 0; i < columSize; i++) { | for (int i = 0; i < columSize; i++) { | ||||
itemList.add(i); | itemList.add(i); | ||||
@@ -348,19 +357,18 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
} | } | ||||
/// item 的数据 | /// item 的数据 | ||||
Widget _getColumWidget({ | |||||
double titleHeight, | |||||
double iconHeight, | |||||
int totalPage, | |||||
int currentPage, | |||||
int columSize, | |||||
int totalRowSize, | |||||
int totalDataSize, | |||||
CustomQuickEntryModel model, | |||||
int currentRow, | |||||
int currentColum, | |||||
double itemHeight, | |||||
}) { | |||||
Widget _getColumWidget( | |||||
{double titleHeight, | |||||
double iconHeight, | |||||
int totalPage, | |||||
int currentPage, | |||||
int columSize, | |||||
int totalRowSize, | |||||
int totalDataSize, | |||||
CustomQuickEntryModel model, | |||||
int currentRow, | |||||
int currentColum, | |||||
double itemHeight}) { | |||||
// 当前index = 当前的页数+1 * 当前的行数 + 当前的列数 | // 当前index = 当前的页数+1 * 当前的行数 + 当前的列数 | ||||
// int currentIndex = (currentPage + 1) * currentRow + currentColum + currentRow*columSize; | // int currentIndex = (currentPage + 1) * currentRow + currentColum + currentRow*columSize; | ||||
// int currentIndex = currentPage != 0 ? currentPage * (columSize * totalRowSize) + columSize + currentRow * columSize : | // int currentIndex = currentPage != 0 ? currentPage * (columSize * totalRowSize) + columSize + currentRow * columSize : | ||||
@@ -389,7 +397,6 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
// color: Colors.red, | // color: Colors.red, | ||||
child: Column( | child: Column( | ||||
children: <Widget>[ | children: <Widget>[ | ||||
/// 图标 | /// 图标 | ||||
MyNetWorkImage(item.img), | MyNetWorkImage(item.img), | ||||
@@ -481,6 +488,10 @@ class __CustomQuickEntryContainerState extends State<_CustomQuickEntryContainer> | |||||
); | ); | ||||
}); | }); | ||||
} | } | ||||
@override | |||||
// TODO: implement wantKeepAlive | |||||
bool get wantKeepAlive => true; | |||||
} | } | ||||
/// | /// | ||||
@@ -495,14 +506,10 @@ class MyNetWorkImage extends StatelessWidget { | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return RepaintBoundary( | return RepaintBoundary( | ||||
child: CachedNetworkImage( | |||||
width: width, | |||||
imageUrl: imgUrl | |||||
), | |||||
child: CachedNetworkImage(width: width, imageUrl: imgUrl), | |||||
); | ); | ||||
} | } | ||||
// Widget _getMainWidget(CustomQuickEntryModel model) { | // Widget _getMainWidget(CustomQuickEntryModel model) { | ||||
// // 数据总数 | // // 数据总数 | ||||
// int totalDataSize = model?.listStyle?.length ?? 0; | // int totalDataSize = model?.listStyle?.length ?? 0; | ||||
@@ -580,3 +587,519 @@ class MyNetWorkImage extends StatelessWidget { | |||||
// } | // } | ||||
} | } | ||||
class CustomQuickCateEntry extends StatefulWidget { | |||||
final CustomQuickEntryModel model; | |||||
const CustomQuickCateEntry({Key key, this.model}) : super(key: key); | |||||
@override | |||||
_CustomQuickCateEntryState createState() => _CustomQuickCateEntryState(); | |||||
} | |||||
class _CustomQuickCateEntryState extends State<CustomQuickCateEntry> with TickerProviderStateMixin, AutomaticKeepAliveClientMixin { | |||||
TabController tabController; | |||||
PrimaryPageController primaryPageController; | |||||
bool isOnTap = false; | |||||
Timer onTapTimer; | |||||
SwiperController _controller; | |||||
List<PageItem> pageList = List(); | |||||
@override | |||||
void initState() { | |||||
// primaryPageController = PrimaryPageController(keepPage: true); | |||||
if (widget?.model != null) { | |||||
tabController = TabController(length: widget?.model?.typeList?.length ?? 0, vsync: this); | |||||
tabController.addListener(() {}); | |||||
} | |||||
_controller = SwiperController(); | |||||
// primaryPageController.addListener(() { | |||||
// if (isOnTap) { | |||||
// return; | |||||
// } | |||||
// if ((primaryPageController.page - tabController.index).abs() > 0.9) { | |||||
// tabController.animateTo(primaryPageController.page.floor()); | |||||
// } | |||||
// }); | |||||
super.initState(); | |||||
} | |||||
@override | |||||
void dispose() { | |||||
tabController?.dispose(); | |||||
primaryPageController?.dispose(); | |||||
for (var item in widget.model?.typeList) { | |||||
item.primaryPageController?.dispose(); | |||||
item.primaryPageController = null; | |||||
} | |||||
super.dispose(); | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
super.build(context); | |||||
print("构建数据"); | |||||
return _getMainHasCategoryWidget(widget?.model); | |||||
} | |||||
Widget _getMainHasCategoryWidget(CustomQuickEntryModel model) { | |||||
bool hasCategory = false; | |||||
if (!EmptyUtil.isEmpty(model?.typeList) && model.typeList.length >= 2) { | |||||
hasCategory = true; | |||||
} | |||||
int maxTotal = 0; | |||||
///分类 | |||||
if (model.typeList != null) { | |||||
for (var item in model?.typeList) { | |||||
item.listStyle = List(); | |||||
if (item.primaryPageController == null) { | |||||
item.primaryPageController = PrimaryPageController(keepPage: true); | |||||
} | |||||
for (var listItem in model?.listStyle) { | |||||
if (listItem?.typeListKey == item.key) { | |||||
item.listStyle.add(listItem); | |||||
} | |||||
} | |||||
if (item.listStyle.length > maxTotal) { | |||||
maxTotal = item.listStyle.length; | |||||
} | |||||
} | |||||
} | |||||
pageList.clear(); | |||||
// 数据总数 | |||||
int totalDataSize = maxTotal; | |||||
// 展示的列数 | |||||
int columSize = int.parse(model?.columSize ?? '5'); | |||||
// 展示的总行数 | |||||
int totalRowSize = int.parse(model?.rowSize ?? '2'); | |||||
//计算实际显示行数 | |||||
if (totalRowSize * columSize > totalDataSize) { | |||||
for (int index = 1; index <= totalRowSize; index++) { | |||||
if (index * columSize >= totalDataSize) { | |||||
totalRowSize = index; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
//计算实际显示行数 | |||||
print("行数" + totalRowSize.toString()); | |||||
// 图标的高度 | |||||
double iconHeight = 40.0; | |||||
// 标题的高度 | |||||
double titleHeight = 20.0; | |||||
// 子元素的高度 | |||||
double itemHeight = iconHeight; | |||||
// 如果有一级标题 | |||||
if (!EmptyUtil.isEmpty(model?.isShowTitle) && model.isShowTitle == '1') { | |||||
itemHeight = iconHeight + titleHeight; | |||||
} | |||||
//如果有二级标题 | |||||
if (!EmptyUtil.isEmpty(model?.isShowSubTitle) && model.isShowSubTitle == '1') { | |||||
itemHeight = iconHeight + titleHeight * 2; | |||||
} | |||||
// 进度条的边距 | |||||
double barMargin = 10.0; | |||||
// 总页数 | |||||
int totalPage = totalDataSize % (totalRowSize * columSize) == 0 ? totalDataSize ~/ (totalRowSize * columSize) : (totalDataSize ~/ (totalRowSize * columSize)) + 1; | |||||
Logger.log('totalPage = ' + totalPage?.toString()); | |||||
// 总体高度 = 行数 * (子元素高度 + 边距高度) + 进度条的高度 | |||||
double totalHeight = totalRowSize * (itemHeight + barMargin); | |||||
if (totalPage > 1 && !EmptyUtil.isEmpty(model?.pagination) && model.pagination != 'type_null' /*model.pagination_open == '0'*/) { | |||||
totalHeight = totalRowSize * (itemHeight + barMargin)+8; | |||||
} | |||||
// 分类导航高度 | |||||
double categoryHeight = 24; | |||||
// 分类导航到多眼导航的边距 | |||||
double categoryBottomMargin = 20.0; | |||||
if (!EmptyUtil.isEmpty(model?.typeList) && model.typeList.length >= 2) { | |||||
totalHeight = totalHeight + categoryHeight + categoryBottomMargin; | |||||
hasCategory = true; | |||||
} | |||||
// 如果有左上角标题 | |||||
double moduleTitleHeight = 22 + 10.0; | |||||
if (!EmptyUtil.isEmpty(model?.moduleTitleName)) { | |||||
totalHeight = totalHeight + moduleTitleHeight; | |||||
} | |||||
double marginLeftRight = model?.isLeftRightMargin == "1" ? double.tryParse(model?.leftRightMargin ?? "0") : 0; | |||||
double marginTop = model?.isTopMargin == "1" ? double.tryParse(model?.topMargin ?? "0") : 0; | |||||
int currentTypeIndex = 0; | |||||
for (var item in model.typeList) { | |||||
if ((item?.listStyle?.length??0) == 0) { | |||||
pageList.add(PageItem(index: currentTypeIndex, listStyle: List())); | |||||
currentTypeIndex++; | |||||
continue; | |||||
} | |||||
if (item.listStyle.length > totalRowSize) { | |||||
for (int index = 0; index < (item.listStyle.length / (columSize * totalRowSize)).ceil(); index++) { | |||||
var list = List<ListStyle>(); | |||||
var startIndex = index * columSize * totalRowSize; | |||||
for (var i = 0; i < columSize * totalRowSize; i++) { | |||||
if (item.listStyle.length > startIndex + i) { | |||||
list.add(item.listStyle[startIndex+i]); | |||||
} else { | |||||
break; | |||||
} | |||||
} | |||||
pageList.add(PageItem(index: currentTypeIndex, listStyle: list)); | |||||
} | |||||
}else{ | |||||
pageList.add(PageItem(index: currentTypeIndex, listStyle: item?.listStyle)); | |||||
} | |||||
currentTypeIndex++; | |||||
} | |||||
return Container( | |||||
margin: EdgeInsets.only(top: marginTop, left: marginLeftRight, right: marginLeftRight), | |||||
decoration: BoxDecoration( | |||||
color: HexColor.fromHex(model?.bgColor ?? ''), | |||||
//color: Colors.green, | |||||
borderRadius: BorderRadius.only( | |||||
topRight: Radius.circular(ParseUtil.stringParseDouble(model?.topRightRadius)), | |||||
topLeft: Radius.circular(ParseUtil.stringParseDouble(model?.topLeftRadius)), | |||||
bottomLeft: Radius.circular(ParseUtil.stringParseDouble(model?.bottomLeftRadius)), | |||||
bottomRight: Radius.circular(ParseUtil.stringParseDouble(model?.bottomRightRadius)), | |||||
)), | |||||
child: Container( | |||||
height: totalHeight+(totalRowSize*5), | |||||
margin: EdgeInsets.only(bottom: model?.pagination=="type_null"?0:8), | |||||
child: Column( | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
children: <Widget>[ | |||||
hasCategory | |||||
? Container( | |||||
height: categoryHeight, | |||||
margin: EdgeInsets.only(top: 10,bottom: 10), | |||||
child: TabBar( | |||||
isScrollable: true, | |||||
onTap: (value) { | |||||
onTapTimer?.cancel(); | |||||
isOnTap=true; | |||||
onTapTimer = Timer(Duration(milliseconds: 300), () { | |||||
isOnTap = false; | |||||
}); | |||||
int current = 0; | |||||
for (var pageItem in pageList) { | |||||
if (pageItem.index == value) { | |||||
_controller.move(current); | |||||
print("跳转到" + current.toString()); | |||||
break; | |||||
} | |||||
current++; | |||||
} | |||||
}, | |||||
labelColor: HexColor.fromHex("#FFFFFF"), | |||||
unselectedLabelColor: HexColor.fromHex("#FF333333"), | |||||
labelStyle: TextStyle(fontSize: 14), | |||||
tabs: _buildTab(model), | |||||
controller: tabController, | |||||
indicatorSize: TabBarIndicatorSize.label, | |||||
indicatorColor: Colors.transparent, | |||||
indicator: BubbleTabIndicator(indicatorColor: HexColor.fromHex("#FF4242")), | |||||
), | |||||
) | |||||
: Container(), | |||||
Expanded( | |||||
child: Swiper( | |||||
controller: _controller, | |||||
itemCount: pageList.length ?? 0, | |||||
physics: BouncingScrollPhysics(), | |||||
loop: false, | |||||
onIndexChanged: (currentIndex) { | |||||
if (isOnTap) { | |||||
return; | |||||
} | |||||
tabController.animateTo(pageList[currentIndex].index); | |||||
}, | |||||
itemBuilder: (context, index) { | |||||
var totalDataSize = pageList[index].listStyle.length ?? 0; | |||||
return Container( | |||||
height: double.infinity, | |||||
width: double.infinity, | |||||
padding: const EdgeInsets.symmetric(horizontal: 4), | |||||
child: _getCategoryPageWidget( | |||||
iconHeight: iconHeight, | |||||
titleHeight: titleHeight, | |||||
totalDataSize: totalDataSize, | |||||
totalPage: pageList?.length??0, | |||||
currentPage: index, | |||||
totalRowSize: totalRowSize, | |||||
columSize: columSize, | |||||
model: model, | |||||
itemHeight: itemHeight, | |||||
), | |||||
); | |||||
}, | |||||
pagination: _getSwiperPaginationContorl(model, model?.typeList?.length ?? 0), | |||||
)), | |||||
], | |||||
), | |||||
), | |||||
); | |||||
} | |||||
_buildTab(CustomQuickEntryModel model) { | |||||
List<Widget> listWidget = List(); | |||||
for (var item in model?.typeList) { | |||||
listWidget.add(Tab( | |||||
text: item.name, | |||||
)); | |||||
} | |||||
return listWidget; | |||||
} | |||||
/// 获取有分类页 | |||||
_getCategoryPageWidget( | |||||
{double titleHeight, | |||||
double iconHeight, | |||||
int totalPage, | |||||
int currentPage, | |||||
int columSize, | |||||
int totalRowSize, | |||||
int totalDataSize, | |||||
CustomQuickEntryModel model, | |||||
double itemHeight}) { | |||||
List rowList = []; | |||||
for (int i = 0; i < totalRowSize; i++) { | |||||
rowList.add(i); | |||||
} | |||||
return Column( | |||||
crossAxisAlignment: CrossAxisAlignment.start, | |||||
mainAxisAlignment: MainAxisAlignment.start, | |||||
children: rowList.map((currentRow) { | |||||
return Container( | |||||
padding: EdgeInsets.only(bottom: 15), | |||||
width: double.infinity, | |||||
child: _buildHasCategoryRowWidget( | |||||
titleHeight: titleHeight, | |||||
iconHeight: iconHeight, | |||||
totalPage: totalPage, | |||||
currentPage: currentPage, | |||||
columSize: columSize, | |||||
totalRowSize: totalRowSize, | |||||
totalDataSize: totalDataSize, | |||||
model: model, | |||||
currentRow: currentRow, | |||||
itemHeight: itemHeight), | |||||
); | |||||
}).toList(), | |||||
); | |||||
} | |||||
///有分类行构建 | |||||
Widget _buildHasCategoryRowWidget( | |||||
{double titleHeight, | |||||
double iconHeight, | |||||
int totalPage, | |||||
int currentPage, | |||||
int columSize, | |||||
int totalRowSize, | |||||
int totalDataSize, | |||||
CustomQuickEntryModel model, | |||||
int currentRow, | |||||
double itemHeight}) { | |||||
List itemList = []; | |||||
for (int i = 0; i < columSize; i++) { | |||||
itemList.add(i); | |||||
} | |||||
return Row( | |||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||||
crossAxisAlignment: CrossAxisAlignment.center, | |||||
children: itemList.map((currentIndex) { | |||||
return _getHasCategoryColumWidget( | |||||
titleHeight: titleHeight, | |||||
iconHeight: iconHeight, | |||||
totalPage: totalPage, | |||||
currentPage: currentPage, | |||||
totalDataSize: totalDataSize, | |||||
columSize: columSize, | |||||
totalRowSize: totalRowSize, | |||||
model: model, | |||||
currentRow: currentRow, | |||||
currentColum: currentIndex, | |||||
itemHeight: itemHeight, | |||||
); | |||||
}).toList(), | |||||
); | |||||
} | |||||
/// item 的数据 | |||||
Widget _getHasCategoryColumWidget({ | |||||
double titleHeight, | |||||
double iconHeight, | |||||
int totalPage, | |||||
int currentPage, | |||||
int columSize, | |||||
int totalRowSize, | |||||
int totalDataSize, | |||||
CustomQuickEntryModel model, | |||||
int currentRow, | |||||
int currentColum, | |||||
double itemHeight, | |||||
}) { | |||||
// 当前index = 当前的页数+1 * 当前的行数 + 当前的列数 | |||||
// int currentIndex = (currentPage + 1) * currentRow + currentColum + currentRow*columSize; | |||||
// int currentIndex = currentPage != 0 ? currentPage * (columSize * totalRowSize) + columSize + currentRow * columSize : | |||||
// currentColum + currentRow * columSize; | |||||
// 当前元素的下表 = 当前的列数 + 当前的行数 * 列数 + 当前的页数 * 当前的行数 + 当前的列数 | |||||
int currentIndex = currentColum + currentRow * columSize ; | |||||
print("当前页"+currentPage.toString()+"当前点"+currentIndex.toString()); | |||||
// print('current Index sss = $currentIndex'); | |||||
if (currentIndex >= totalDataSize) { | |||||
return Container( | |||||
height: itemHeight, | |||||
width: 60, | |||||
); | |||||
} | |||||
ListStyle item = pageList[currentPage].listStyle[currentIndex]; | |||||
return GestureDetector( | |||||
behavior: HitTestBehavior.opaque, | |||||
onTap: () => _itemIconClick(item), | |||||
child: Container( | |||||
height: itemHeight, | |||||
width: 60, | |||||
// color: Colors.red, | |||||
child: Column( | |||||
children: <Widget>[ | |||||
/// 图标 | |||||
MyNetWorkImage(item.img), | |||||
/// 一级标题 | |||||
Visibility( | |||||
visible: !EmptyUtil.isEmpty(model?.isShowTitle) && model.isShowTitle == '1', | |||||
child: Padding( | |||||
padding: const EdgeInsets.only(top: 5), | |||||
child: Text( | |||||
item?.title ?? '', | |||||
style: TextStyle(fontSize: 10, color: HexColor.fromHex(model?.titleColor)), | |||||
), | |||||
), | |||||
), | |||||
/// 二级标题 | |||||
Visibility( | |||||
visible: !EmptyUtil.isEmpty(model?.isShowSubTitle) && model.isShowSubTitle == '1', | |||||
child: Padding( | |||||
padding: const EdgeInsets.only(top: 5), | |||||
child: Text( | |||||
item?.subTitle ?? '', | |||||
style: TextStyle(fontSize: 10, color: HexColor.fromHex(model?.subTitleColor)), | |||||
), | |||||
), | |||||
) | |||||
], | |||||
), | |||||
), | |||||
); | |||||
} | |||||
/// Icon点击事件 | |||||
void _itemIconClick(ListStyle model) { | |||||
print("item type = ${model.skipIdentifier}"); | |||||
// Navigator.push(context, CupertinoPageRoute(builder: (_) => CommonPage(null))); | |||||
RouterUtil.route(model, model.toJson(), context); | |||||
} | |||||
/// 进度条 | |||||
SwiperPlugin _getSwiperPaginationContorl(CustomQuickEntryModel model, int pageCount) { | |||||
if (EmptyUtil.isEmpty(model?.pagination) || model.pagination == 'type_null' /*model.pagination_open == '0'*/) { | |||||
return null; | |||||
} | |||||
if (model.pagination == 'type_point') { | |||||
// 点点点进度条 | |||||
return _swiperPaginationDot(model); | |||||
} else { | |||||
// 自定义进度条 | |||||
return _swiperCustomPagination(pageCount); | |||||
} | |||||
} | |||||
// 进度条 圆形 | |||||
SwiperPagination _swiperPaginationDot(CustomQuickEntryModel model) { | |||||
return SwiperPagination( | |||||
margin: const EdgeInsets.only(), | |||||
builder: DotSwiperPaginationBuilder( | |||||
color: HexColor.fromHex(model?.paginationUnselectColor), activeColor: HexColor.fromHex(model?.paginationSelectColor), size: 8, activeSize: 8)); | |||||
} | |||||
// 自定义进度条 条形 | |||||
SwiperPlugin _swiperCustomPagination(int pageCount) { | |||||
List list = []; | |||||
for (int i = 0; i < pageCount; i++) { | |||||
list.add(i); | |||||
} | |||||
return SwiperCustomPagination(builder: (BuildContext context, SwiperPluginConfig config) { | |||||
return Align( | |||||
alignment: Alignment(0.0, 1), | |||||
child: Row( | |||||
mainAxisAlignment: MainAxisAlignment.center, | |||||
crossAxisAlignment: CrossAxisAlignment.center, | |||||
children: list.map((index) { | |||||
var borderRadius; | |||||
if (index == 0) { | |||||
borderRadius = BorderRadius.only(topLeft: Radius.circular(2), bottomLeft: Radius.circular(2)); | |||||
} | |||||
if (index == list.length - 1) { | |||||
borderRadius = BorderRadius.only(topRight: Radius.circular(2), bottomRight: Radius.circular(2)); | |||||
} | |||||
if (index == config.activeIndex) { | |||||
borderRadius = BorderRadius.all(Radius.circular(2)); | |||||
} | |||||
return Container( | |||||
height: 4, | |||||
width: 25, | |||||
decoration: BoxDecoration(borderRadius: borderRadius, color: index == config.activeIndex ? HexColor.fromHex('#FF4242') : HexColor.fromHex('#FFFFFF')), | |||||
); | |||||
}).toList(), | |||||
), | |||||
); | |||||
}); | |||||
} | |||||
@override | |||||
// TODO: implement wantKeepAlive | |||||
bool get wantKeepAlive => true; | |||||
} | |||||
class PageItem { | |||||
int index; | |||||
PageItem({this.index, this.listStyle}); | |||||
List<ListStyle> listStyle; | |||||
} |
@@ -1,4 +1,5 @@ | |||||
import 'package:zhiying_base_widget/dialog/global_dialog/intellect_search_goods_dialog/model/no_goods_dialog_style_model.dart'; | import 'package:zhiying_base_widget/dialog/global_dialog/intellect_search_goods_dialog/model/no_goods_dialog_style_model.dart'; | ||||
import 'package:zhiying_base_widget/widgets/primary_page_view/primary_page_view.dart'; | |||||
import 'package:zhiying_comm/zhiying_comm.dart'; | import 'package:zhiying_comm/zhiying_comm.dart'; | ||||
class CustomQuickEntryModel { | class CustomQuickEntryModel { | ||||
@@ -191,6 +192,9 @@ class ListStyle extends SkipModel{ | |||||
class TypeList { | class TypeList { | ||||
String name; | String name; | ||||
String key; | String key; | ||||
List<ListStyle> listStyle; | |||||
PrimaryPageController primaryPageController; | |||||
int index; | |||||
TypeList({this.name, this.key}); | TypeList({this.name, this.key}); | ||||
@@ -21,7 +21,7 @@ import 'package:zhiying_comm/util/turn_chain/turn_chain_util.dart'; | |||||
class GoodsDetailsFooterWidget extends StatelessWidget { | class GoodsDetailsFooterWidget extends StatelessWidget { | ||||
final Map<String, dynamic> model; | final Map<String, dynamic> model; | ||||
final bool isFree; | final bool isFree; | ||||
const GoodsDetailsFooterWidget(this.model,{this.isFree}); | |||||
const GoodsDetailsFooterWidget(this.model,{this.isFree=false}); | |||||
@override | @override | ||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
@@ -34,6 +34,7 @@ class GoodsDetailsFooterWidget extends StatelessWidget { | |||||
child: _GoodsDetailsFooterContainer( | child: _GoodsDetailsFooterContainer( | ||||
model, | model, | ||||
key: UniqueKey(), | key: UniqueKey(), | ||||
isFree: isFree, | |||||
), | ), | ||||
), | ), | ||||
); | ); | ||||
@@ -144,7 +144,7 @@ class _UpgradeTipWidgetState extends State<UpgradeTipWidget> { | |||||
return _isiOSReview ? Container() : Container( | return _isiOSReview ? Container() : Container( | ||||
width: double.infinity, | width: double.infinity, | ||||
margin: EdgeInsets.only(top: ParseUtil.stringParseDouble(widget._model?.topMargin), left: ParseUtil.stringParseDouble(widget._model?.leftRightMargin), right: ParseUtil.stringParseDouble(widget._model?.leftRightMargin)), | margin: EdgeInsets.only(top: ParseUtil.stringParseDouble(widget._model?.topMargin), left: ParseUtil.stringParseDouble(widget._model?.leftRightMargin), right: ParseUtil.stringParseDouble(widget._model?.leftRightMargin)), | ||||
padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 6, bottom: 6), | |||||
padding: const EdgeInsets.only(left: 10, right: 10, top: 0, bottom: 0), | |||||
decoration: BoxDecoration( | decoration: BoxDecoration( | ||||
color: HexColor.fromHex(widget._model?.bgColor), | color: HexColor.fromHex(widget._model?.bgColor), | ||||
// color: Colors.white, | // color: Colors.white, | ||||
@@ -163,7 +163,7 @@ class _UpgradeTipWidgetState extends State<UpgradeTipWidget> { | |||||
color: HexColor.fromHex(widget._model?.bulletinBgColor ?? '#FFEFDA'), | color: HexColor.fromHex(widget._model?.bulletinBgColor ?? '#FFEFDA'), | ||||
borderRadius: BorderRadius.circular(30), | borderRadius: BorderRadius.circular(30), | ||||
), | ), | ||||
padding: const EdgeInsets.only(left: 10, right: 13, top: 10, bottom: 10), | |||||
padding: const EdgeInsets.only(left: 10,right: 10,top: 9.5, bottom: 9.5), | |||||
child: Row( | child: Row( | ||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
children: <Widget>[ | children: <Widget>[ | ||||
@@ -185,19 +185,20 @@ class _UpgradeTipWidgetState extends State<UpgradeTipWidget> { | |||||
CachedNetworkImage( | CachedNetworkImage( | ||||
imageUrl: model?.icon ?? '', | imageUrl: model?.icon ?? '', | ||||
width: 15, | width: 15, | ||||
fit: BoxFit.fitWidth, | |||||
), | ), | ||||
const SizedBox(width: 7.5), | const SizedBox(width: 7.5), | ||||
/// 文字 | /// 文字 | ||||
Text(model?.bulletinText ?? '下载APP升级运营商,享受更多收益', style: TextStyle(color: HexColor.fromHex(model?.bulletinTextColor ?? '#C09023'), fontSize: 11)) | |||||
Text(model?.bulletinText ?? '下载APP升级运营商,享受更多收益', style: TextStyle(color: HexColor.fromHex(model?.bulletinTextColor ?? '#C09023'), height: 1,fontSize: 11)) | |||||
], | ], | ||||
); | ); | ||||
} | } | ||||
/// 右边的视图 | /// 右边的视图 | ||||
Widget _getRightWidget(UpgradeTipModel model) { | Widget _getRightWidget(UpgradeTipModel model) { | ||||
return Text(model?.goText ?? '前往下载', style: TextStyle(color: HexColor.fromHex(model?.bulletinTextColor ?? '#C09023'), fontSize: 11)); | |||||
return Text(model?.goText ?? '前往下载', style: TextStyle(color: HexColor.fromHex(model?.bulletinTextColor ?? '#C09023'),height: 1, fontSize: 11)); | |||||
// return Row( | // return Row( | ||||
// children: <Widget>[ | // children: <Widget>[ | ||||
// Text(model?.go_text ??'前往下载', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11)), | // Text(model?.go_text ??'前往下载', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11)), | ||||
@@ -102,38 +102,41 @@ class _MineHeaderContainerState extends State<MineHeaderContainer> { | |||||
fontSize: 17, color: HexColor.fromHex(widget.staticModel.userNameColor)), | fontSize: 17, color: HexColor.fromHex(widget.staticModel.userNameColor)), | ||||
), | ), | ||||
), | ), | ||||
Container( | |||||
height: 18, | |||||
margin: EdgeInsets.only(left: 6), | |||||
padding: EdgeInsets.only(left: 6, right: 6), | |||||
decoration: boxDecoration, | |||||
// BoxDecoration( | |||||
// image: DecorationImage( | |||||
// fit: BoxFit.fitWidth, | |||||
// image: NetworkImage( | |||||
// widget.staticModel.lvBgImage, | |||||
// | |||||
// )), | |||||
// // color: HexColor.fromHex(widget.staticModel.bgColor), | |||||
// // borderRadius: BorderRadius.circular(9) | |||||
// ), | |||||
child: Row( | |||||
children: <Widget>[ | |||||
Container( | |||||
width: 12, | |||||
height: 12, | |||||
margin: EdgeInsets.only(right: 2), | |||||
child: CachedNetworkImage( | |||||
imageUrl: profile?.userLvIcon ?? '', | |||||
fit: BoxFit.contain, | |||||
Visibility( | |||||
visible: (widget?.staticModel?.status??"1")=="1"?true:false, | |||||
child: Container( | |||||
height: 18, | |||||
margin: EdgeInsets.only(left: 6), | |||||
padding: EdgeInsets.only(left: 6, right: 6), | |||||
decoration: boxDecoration, | |||||
// BoxDecoration( | |||||
// image: DecorationImage( | |||||
// fit: BoxFit.fitWidth, | |||||
// image: NetworkImage( | |||||
// widget.staticModel.lvBgImage, | |||||
// | |||||
// )), | |||||
// // color: HexColor.fromHex(widget.staticModel.bgColor), | |||||
// // borderRadius: BorderRadius.circular(9) | |||||
// ), | |||||
child: Row( | |||||
children: <Widget>[ | |||||
Container( | |||||
width: 12, | |||||
height: 12, | |||||
margin: EdgeInsets.only(right: 2), | |||||
child: CachedNetworkImage( | |||||
imageUrl: profile?.userLvIcon ?? '', | |||||
fit: BoxFit.contain, | |||||
), | |||||
), | ), | ||||
), | |||||
Text( | |||||
profile?.userLvName ?? '', | |||||
style: TextStyle( | |||||
fontSize: 10, color: HexColor.fromHex(widget.staticModel.lvNameColor)), | |||||
) | |||||
], | |||||
Text( | |||||
profile?.userLvName ?? '', | |||||
style: TextStyle( | |||||
fontSize: 10, color: HexColor.fromHex(widget.staticModel.lvNameColor)), | |||||
) | |||||
], | |||||
), | |||||
), | ), | ||||
), | ), | ||||
], | ], | ||||
@@ -30,6 +30,7 @@ class MineHeaderModel { | |||||
int requiredLogin; | int requiredLogin; | ||||
int requiredTaobaoAuth; | int requiredTaobaoAuth; | ||||
String skipIdentifier; | String skipIdentifier; | ||||
String status; | |||||
MineHeaderModel( | MineHeaderModel( | ||||
{this.name, | {this.name, | ||||
@@ -96,6 +97,7 @@ class MineHeaderModel { | |||||
requiredLogin = json['required_login']; | requiredLogin = json['required_login']; | ||||
requiredTaobaoAuth = json['required_taobao_auth']; | requiredTaobaoAuth = json['required_taobao_auth']; | ||||
skipIdentifier = json['skip_identifier']; | skipIdentifier = json['skip_identifier']; | ||||
status=json['status']; | |||||
} | } | ||||
Map<String, dynamic> toJson() { | Map<String, dynamic> toJson() { | ||||
@@ -0,0 +1,980 @@ | |||||
import 'dart:async'; | |||||
import 'dart:math' as math; | |||||
import 'package:flutter/material.dart'; | |||||
import 'package:flutter/physics.dart'; | |||||
import 'package:flutter/rendering.dart'; | |||||
import 'package:flutter/gestures.dart' show Drag, DragStartBehavior; | |||||
import 'package:flutter/foundation.dart' show precisionErrorTolerance; | |||||
///支持嵌套滑动的pageView | |||||
///需要开启Primary=true | |||||
class PrimaryPageController extends ScrollController { | |||||
PrimaryPageController({ | |||||
this.initialPage = 0, | |||||
this.keepPage = true, | |||||
this.viewportFraction = 1.0, | |||||
this.coordinator, | |||||
}) : assert(initialPage != null), | |||||
assert(keepPage != null), | |||||
assert(viewportFraction != null), | |||||
assert(viewportFraction > 0.0); | |||||
int initialPage; | |||||
final bool keepPage; | |||||
final double viewportFraction; | |||||
PrimaryPageCoordinator coordinator; | |||||
List<PrimaryPageController> childPageController = []; | |||||
double get page { | |||||
assert( | |||||
positions.isNotEmpty, | |||||
'PrimaryPageController.page cannot be accessed before a NestedPrimaryPageView is built with it.', | |||||
); | |||||
assert( | |||||
positions.length == 1, | |||||
'The page property cannot be read when multiple PageViews are attached to ' | |||||
'the same PrimaryPageController.', | |||||
); | |||||
final PrimaryPagePosition position = this.position; | |||||
return position.page; | |||||
} | |||||
Future<void> animateToPage( | |||||
int page, { | |||||
@required Duration duration, | |||||
@required Curve curve, | |||||
}) { | |||||
final PrimaryPagePosition position = this.position; | |||||
return position.animateTo( | |||||
position.getPixelsFromPage(page.toDouble()), | |||||
duration: duration, | |||||
curve: curve, | |||||
); | |||||
} | |||||
void jumpToPage(int page) { | |||||
final PrimaryPagePosition position = this.position; | |||||
position.jumpTo(position.getPixelsFromPage(page.toDouble())); | |||||
} | |||||
Future<void> nextPage({@required Duration duration, @required Curve curve}) { | |||||
return animateToPage(page.round() + 1, duration: duration, curve: curve); | |||||
} | |||||
Future<void> previousPage( | |||||
{@required Duration duration, @required Curve curve}) { | |||||
return animateToPage(page.round() - 1, duration: duration, curve: curve); | |||||
} | |||||
@override | |||||
ScrollPosition createScrollPosition(ScrollPhysics physics, | |||||
ScrollContext context, ScrollPosition oldPosition) { | |||||
PrimaryPagePosition result = PrimaryPagePosition( | |||||
physics: physics, | |||||
context: context, | |||||
initialPage: initialPage, | |||||
keepPage: keepPage, | |||||
viewportFraction: viewportFraction, | |||||
oldPosition: oldPosition, | |||||
)..coordinator = coordinator; | |||||
return result; | |||||
} | |||||
@override | |||||
void attach(ScrollPosition position) { | |||||
super.attach(position); | |||||
final PrimaryPagePosition pagePosition = position; | |||||
pagePosition.viewportFraction = viewportFraction; | |||||
if (position is PrimaryPagePosition) { | |||||
position.coordinator = coordinator; | |||||
} | |||||
} | |||||
@override | |||||
void detach(ScrollPosition position) { | |||||
super.detach(position); | |||||
} | |||||
} | |||||
class PrimaryPagePosition extends ScrollPosition | |||||
implements PageMetrics, ScrollActivityDelegate { | |||||
PrimaryPagePosition({ | |||||
ScrollPhysics physics, | |||||
ScrollContext context, | |||||
this.initialPage = 0, | |||||
bool keepPage = true, | |||||
double viewportFraction = 1.0, | |||||
double initialPixels = 0.0, | |||||
ScrollPosition oldPosition, | |||||
}) : assert(initialPage != null), | |||||
assert(keepPage != null), | |||||
assert(viewportFraction != null), | |||||
assert(viewportFraction > 0.0), | |||||
_viewportFraction = viewportFraction, | |||||
_pageToUseOnStartup = initialPage.toDouble(), | |||||
super( | |||||
physics: physics, | |||||
context: context, | |||||
keepScrollOffset: keepPage, | |||||
oldPosition: oldPosition, | |||||
) { | |||||
if (activity == null) goIdle(); | |||||
assert(activity != null); | |||||
} | |||||
final int initialPage; | |||||
double _pageToUseOnStartup; | |||||
@override | |||||
double get viewportFraction => _viewportFraction; | |||||
double _viewportFraction; | |||||
PrimaryPageCoordinator coordinator; | |||||
set viewportFraction(double value) { | |||||
if (_viewportFraction == value) return; | |||||
final double oldPage = page; | |||||
_viewportFraction = value; | |||||
if (oldPage != null) forcePixels(getPixelsFromPage(oldPage)); | |||||
} | |||||
double get _initialPageOffset => | |||||
math.max(0, viewportDimension * (viewportFraction - 1) / 2); | |||||
ScrollActivity get scrollActivity => activity; | |||||
double getPageFromPixels(double pixels, double viewportDimension) { | |||||
final double actual = math.max(0.0, pixels - _initialPageOffset) / | |||||
math.max(1.0, viewportDimension * viewportFraction); | |||||
final double round = actual.roundToDouble(); | |||||
if ((actual - round).abs() < precisionErrorTolerance) { | |||||
return round; | |||||
} | |||||
return actual; | |||||
} | |||||
double getPixelsFromPage(double page) { | |||||
return page * viewportDimension * viewportFraction + _initialPageOffset; | |||||
} | |||||
@override | |||||
double get page { | |||||
assert( | |||||
pixels == null || (minScrollExtent != null && maxScrollExtent != null), | |||||
'Page value is only available after content dimensions are established.', | |||||
); | |||||
return pixels == null | |||||
? null | |||||
: getPageFromPixels( | |||||
pixels.clamp(minScrollExtent, maxScrollExtent), viewportDimension); | |||||
} | |||||
@override | |||||
void saveScrollOffset() { | |||||
PageStorage.of(context.storageContext)?.writeState( | |||||
context.storageContext, getPageFromPixels(pixels, viewportDimension)); | |||||
} | |||||
@override | |||||
void restoreScrollOffset() { | |||||
if (pixels == null) { | |||||
final double value = PageStorage.of(context.storageContext) | |||||
?.readState(context.storageContext); | |||||
if (value != null) _pageToUseOnStartup = value; | |||||
} | |||||
} | |||||
@override | |||||
bool applyViewportDimension(double viewportDimension) { | |||||
final double oldViewportDimensions = this.viewportDimension; | |||||
final bool result = super.applyViewportDimension(viewportDimension); | |||||
final double oldPixels = pixels; | |||||
final double page = (oldPixels == null || oldViewportDimensions == 0.0) | |||||
? _pageToUseOnStartup | |||||
: getPageFromPixels(oldPixels, this.viewportDimension); | |||||
final double newPixels = getPixelsFromPage(page); | |||||
if (newPixels != oldPixels) { | |||||
correctPixels(newPixels); | |||||
return false; | |||||
} | |||||
return result; | |||||
} | |||||
@override | |||||
bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) { | |||||
final double newMinScrollExtent = minScrollExtent + _initialPageOffset; | |||||
return super.applyContentDimensions( | |||||
newMinScrollExtent, | |||||
math.max(newMinScrollExtent, maxScrollExtent - _initialPageOffset), | |||||
); | |||||
} | |||||
@override | |||||
PageMetrics copyWith({ | |||||
double minScrollExtent, | |||||
double maxScrollExtent, | |||||
double pixels, | |||||
double viewportDimension, | |||||
AxisDirection axisDirection, | |||||
double viewportFraction, | |||||
}) { | |||||
return PageMetrics( | |||||
minScrollExtent: minScrollExtent ?? this.minScrollExtent, | |||||
maxScrollExtent: maxScrollExtent ?? this.maxScrollExtent, | |||||
pixels: pixels ?? this.pixels, | |||||
viewportDimension: viewportDimension ?? this.viewportDimension, | |||||
axisDirection: axisDirection ?? this.axisDirection, | |||||
viewportFraction: viewportFraction ?? this.viewportFraction, | |||||
); | |||||
} | |||||
/// Velocity from a previous activity temporarily held by [hold] to potentially | |||||
/// transfer to a next activity. | |||||
double _heldPreviousVelocity = 0.0; | |||||
@override | |||||
AxisDirection get axisDirection => context.axisDirection; | |||||
@override | |||||
double setPixels(double newPixels) { | |||||
print("current position:" + newPixels.toString()); | |||||
return super.setPixels(newPixels); | |||||
} | |||||
@override | |||||
void absorb(ScrollPosition other) { | |||||
super.absorb(other); | |||||
if (other is! ScrollPositionWithSingleContext) { | |||||
goIdle(); | |||||
return; | |||||
} | |||||
activity.updateDelegate(this); | |||||
final PrimaryPagePosition typedOther = other; | |||||
_userScrollDirection = typedOther._userScrollDirection; | |||||
assert(_currentDrag == null); | |||||
if (typedOther._currentDrag != null) { | |||||
_currentDrag = typedOther._currentDrag; | |||||
_currentDrag.updateDelegate(this); | |||||
typedOther._currentDrag = null; | |||||
} | |||||
} | |||||
@override | |||||
void applyNewDimensions() { | |||||
super.applyNewDimensions(); | |||||
context.setCanDrag(physics.shouldAcceptUserOffset(this)); | |||||
} | |||||
@override | |||||
void beginActivity(ScrollActivity newActivity) { | |||||
_heldPreviousVelocity = 0.0; | |||||
if (newActivity == null) return; | |||||
super.beginActivity(newActivity); | |||||
_currentDrag?.dispose(); | |||||
_currentDrag = null; | |||||
if (!activity.isScrolling) updateUserScrollDirection(ScrollDirection.idle); | |||||
} | |||||
@override | |||||
void applyUserOffset(double delta) { | |||||
updateUserScrollDirection( | |||||
delta > 0.0 ? ScrollDirection.forward : ScrollDirection.reverse); | |||||
setPixels(pixels - physics.applyPhysicsToUserOffset(this, delta)); | |||||
} | |||||
@override | |||||
void goIdle() { | |||||
beginActivity(IdleScrollActivity(this)); | |||||
} | |||||
/// Start a physics-driven simulation that settles the [pixels] position, | |||||
/// starting at a particular velocity. | |||||
/// | |||||
/// This method defers to [ScrollPhysics.createBallisticSimulation], which | |||||
/// typically provides a bounce simulation when the current position is out of | |||||
/// bounds and a friction simulation when the position is in bounds but has a | |||||
/// non-zero velocity. | |||||
/// | |||||
/// The velocity should be in logical pixels per second. | |||||
@override | |||||
void goBallistic(double velocity) { | |||||
assert(pixels != null); | |||||
final Simulation simulation = | |||||
physics.createBallisticSimulation(this, velocity); | |||||
if (simulation != null) { | |||||
beginActivity(BallisticScrollActivity(this, simulation, context.vsync)); | |||||
} else { | |||||
goIdle(); | |||||
} | |||||
} | |||||
@override | |||||
ScrollDirection get userScrollDirection => _userScrollDirection; | |||||
ScrollDirection _userScrollDirection = ScrollDirection.idle; | |||||
/// Set [userScrollDirection] to the given value. | |||||
/// | |||||
/// If this changes the value, then a [UserScrollNotification] is dispatched. | |||||
@protected | |||||
@visibleForTesting | |||||
void updateUserScrollDirection(ScrollDirection value) { | |||||
assert(value != null); | |||||
if (userScrollDirection == value) return; | |||||
_userScrollDirection = value; | |||||
didUpdateScrollDirection(value); | |||||
} | |||||
@override | |||||
Future<void> animateTo( | |||||
double to, { | |||||
@required Duration duration, | |||||
@required Curve curve, | |||||
}) { | |||||
if (nearEqual(to, pixels, physics.tolerance.distance)) { | |||||
// Skip the animation, go straight to the position as we are already close. | |||||
jumpTo(to); | |||||
return Future<void>.value(); | |||||
} | |||||
final DrivenScrollActivity activity = DrivenScrollActivity( | |||||
this, | |||||
from: pixels, | |||||
to: to, | |||||
duration: duration, | |||||
curve: curve, | |||||
vsync: context.vsync, | |||||
); | |||||
beginActivity(activity); | |||||
return activity.done; | |||||
} | |||||
@override | |||||
void jumpTo(double value) { | |||||
goIdle(); | |||||
if (pixels != value) { | |||||
final double oldPixels = pixels; | |||||
forcePixels(value); | |||||
notifyListeners(); | |||||
didStartScroll(); | |||||
didUpdateScrollPositionBy(pixels - oldPixels); | |||||
didEndScroll(); | |||||
} | |||||
goBallistic(0.0); | |||||
} | |||||
@Deprecated( | |||||
'This will lead to bugs.') // ignore: flutter_deprecation_syntax, https://github.com/flutter/flutter/issues/44609 | |||||
@override | |||||
void jumpToWithoutSettling(double value) { | |||||
goIdle(); | |||||
if (pixels != value) { | |||||
final double oldPixels = pixels; | |||||
forcePixels(value); | |||||
notifyListeners(); | |||||
didStartScroll(); | |||||
didUpdateScrollPositionBy(pixels - oldPixels); | |||||
didEndScroll(); | |||||
} | |||||
} | |||||
@override | |||||
ScrollHoldController hold(VoidCallback holdCancelCallback) { | |||||
if (coordinator != null && coordinator.isOuterControllerEnable()) { | |||||
return coordinator.hold(holdCancelCallback); | |||||
} else { | |||||
final double previousVelocity = activity.velocity; | |||||
final HoldScrollActivity holdActivity = HoldScrollActivity( | |||||
delegate: this, | |||||
onHoldCanceled: holdCancelCallback, | |||||
); | |||||
beginActivity(holdActivity); | |||||
_heldPreviousVelocity = previousVelocity; | |||||
return holdActivity; | |||||
} | |||||
} | |||||
ScrollDragController _currentDrag; | |||||
@override | |||||
Drag drag(DragStartDetails details, VoidCallback dragCancelCallback) { | |||||
if (coordinator != null && coordinator.isOuterControllerEnable()) { | |||||
return coordinator.drag(details, dragCancelCallback); | |||||
} else { | |||||
final ScrollDragController drag = ScrollDragController( | |||||
delegate: this.coordinator ?? this, | |||||
details: details, | |||||
onDragCanceled: dragCancelCallback, | |||||
carriedVelocity: physics.carriedMomentum(_heldPreviousVelocity), | |||||
motionStartDistanceThreshold: physics.dragStartDistanceMotionThreshold, | |||||
); | |||||
beginActivity(DragScrollActivity(this, drag)); | |||||
assert(_currentDrag == null); | |||||
_currentDrag = drag; | |||||
return drag; | |||||
} | |||||
} | |||||
@override | |||||
void dispose() { | |||||
_currentDrag?.dispose(); | |||||
_currentDrag = null; | |||||
super.dispose(); | |||||
} | |||||
@override | |||||
void debugFillDescription(List<String> description) { | |||||
super.debugFillDescription(description); | |||||
description.add('${context.runtimeType}'); | |||||
description.add('$physics'); | |||||
description.add('$activity'); | |||||
description.add('$userScrollDirection'); | |||||
} | |||||
// Returns the amount of delta that was not used. | |||||
// | |||||
// Positive delta means going down (exposing stuff above), negative delta | |||||
// going up (exposing stuff below). | |||||
double applyClampedDragUpdate(double delta) { | |||||
assert(delta != 0.0); | |||||
// If we are going towards the maxScrollExtent (negative scroll offset), | |||||
// then the furthest we can be in the minScrollExtent direction is negative | |||||
// infinity. For example, if we are already overscrolled, then scrolling to | |||||
// reduce the overscroll should not disallow the overscroll. | |||||
// | |||||
// If we are going towards the minScrollExtent (positive scroll offset), | |||||
// then the furthest we can be in the minScrollExtent direction is wherever | |||||
// we are now, if we are already overscrolled (in which case pixels is less | |||||
// than the minScrollExtent), or the minScrollExtent if we are not. | |||||
// | |||||
// In other words, we cannot, via applyClampedDragUpdate, _enter_ an | |||||
// overscroll situation. | |||||
// | |||||
// An overscroll situation might be nonetheless entered via several means. | |||||
// One is if the physics allow it, via applyFullDragUpdate (see below). An | |||||
// overscroll situation can also be forced, e.g. if the scroll position is | |||||
// artificially set using the scroll controller. | |||||
final double min = | |||||
delta < 0.0 ? -double.infinity : math.min(minScrollExtent, pixels); | |||||
// The logic for max is equivalent but on the other side. | |||||
final double max = | |||||
delta > 0.0 ? double.infinity : math.max(maxScrollExtent, pixels); | |||||
final double oldPixels = pixels; | |||||
final double newPixels = (pixels - delta).clamp(min, max); | |||||
final double clampedDelta = newPixels - pixels; | |||||
if (clampedDelta == 0.0) return delta; | |||||
final double overscroll = physics.applyBoundaryConditions(this, newPixels); | |||||
final double actualNewPixels = newPixels - overscroll; | |||||
final double offset = actualNewPixels - oldPixels; | |||||
if (offset != 0.0) { | |||||
forcePixels(actualNewPixels); | |||||
didUpdateScrollPositionBy(offset); | |||||
} | |||||
return delta + offset; | |||||
} | |||||
// Returns the overscroll. | |||||
double applyFullDragUpdate(double delta) { | |||||
assert(delta != 0.0); | |||||
final double oldPixels = pixels; | |||||
// Apply friction: | |||||
final double newPixels = | |||||
pixels - physics.applyPhysicsToUserOffset(this, delta); | |||||
if (oldPixels == newPixels) | |||||
return 0.0; // delta must have been so small we dropped it during floating point addition | |||||
// Check for overscroll: | |||||
final double overscroll = physics.applyBoundaryConditions(this, newPixels); | |||||
final double actualNewPixels = newPixels - overscroll; | |||||
if (actualNewPixels != oldPixels) { | |||||
forcePixels(actualNewPixels); | |||||
didUpdateScrollPositionBy(actualNewPixels - oldPixels); | |||||
} | |||||
if (overscroll != 0.0) { | |||||
didOverscrollBy(overscroll); | |||||
return overscroll; | |||||
} | |||||
return 0.0; | |||||
} | |||||
} | |||||
class PrimaryPageCoordinator | |||||
implements ScrollActivityDelegate, ScrollHoldController { | |||||
PrimaryPageController _outerController; | |||||
PrimaryPageController _selfController; | |||||
ScrollDragController _currentDrag; | |||||
bool isOperateBody = false; | |||||
PrimaryPageCoordinator(PrimaryPageController selfController, | |||||
PrimaryPageController parentController) { | |||||
_selfController = selfController; | |||||
_selfController.coordinator = this; | |||||
_outerController = parentController; | |||||
_outerController.coordinator = this; | |||||
if (!_outerController.childPageController.contains(_selfController)) { | |||||
_outerController.childPageController.add(_selfController); | |||||
} | |||||
} | |||||
PrimaryPageController getOuterController() { | |||||
return _outerController; | |||||
} | |||||
bool isOuterControllerEnable() { | |||||
return _outerController != null && _outerController.hasClients; | |||||
} | |||||
PrimaryPageController getInnerController() { | |||||
return _selfController; | |||||
} | |||||
bool isInnerControllerEnable() { | |||||
return _selfController != null && _selfController.hasClients; | |||||
} | |||||
@override | |||||
void applyUserOffset(double delta) { | |||||
updateUserScrollDirection( | |||||
delta > 0.0 ? ScrollDirection.forward : ScrollDirection.reverse); | |||||
// PrimaryPagePosition innerPosition = | |||||
// (getInnerController().position as PrimaryPagePosition); | |||||
PrimaryPagePosition outPosition = isOuterControllerEnable() | |||||
? (getOuterController().position as PrimaryPagePosition) | |||||
: null; | |||||
// /// 如果不在头尾,且内部page可滑动 | |||||
// if ((outPosition.pixels > outPosition?.minScrollExtent && | |||||
// outPosition.pixels < outPosition?.maxScrollExtent) && | |||||
// (delta < 0 | |||||
// ? innerPosition.pixels < innerPosition.maxScrollExtent | |||||
// : innerPosition.pixels > innerPosition.minScrollExtent)) { | |||||
// isOperateBody = true; | |||||
// innerPosition.applyUserOffset(delta); | |||||
// return; | |||||
// } | |||||
/// 如果快速滑动,没结束掉动画那种,那么在这里判断下是否需要传给子Page | |||||
if ((outPosition.pixels >= outPosition?.minScrollExtent && | |||||
outPosition.pixels <= outPosition?.maxScrollExtent)) { | |||||
// if (outPosition.pixels % outPosition.viewportDimension != 0) { | |||||
// outPosition.applyUserOffset(delta); | |||||
// return; | |||||
// } | |||||
if (getOuterController().childPageController.length > | |||||
outPosition.page.round()) { | |||||
PrimaryPageController currentChildPageController = | |||||
getOuterController().childPageController[outPosition.page.round()]; | |||||
PrimaryPagePosition currentInnerPosition = | |||||
currentChildPageController.position; | |||||
if (delta < 0 | |||||
? currentInnerPosition.pixels < currentInnerPosition.maxScrollExtent | |||||
: currentInnerPosition.pixels > | |||||
currentInnerPosition.minScrollExtent) { | |||||
isOperateBody = true; | |||||
outPosition.goBallistic(0.0); | |||||
currentInnerPosition.applyUserOffset(delta); | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
/// 都不符合,那才通过外部滑动 | |||||
isOperateBody = false; | |||||
outPosition.applyUserOffset(delta); | |||||
} | |||||
@override | |||||
AxisDirection get axisDirection => _outerController.position.axisDirection; | |||||
@override | |||||
void cancel() { | |||||
goBallistic(0.0); | |||||
} | |||||
@override | |||||
void goBallistic(double velocity) { | |||||
PrimaryPagePosition outPosition = isOuterControllerEnable() | |||||
? (getOuterController().position as PrimaryPagePosition) | |||||
: null; | |||||
if (getOuterController().childPageController.length > | |||||
outPosition.page.round()) { | |||||
PrimaryPageController currentChildPageController = | |||||
getOuterController().childPageController[outPosition.page.round()]; | |||||
PrimaryPagePosition currentInnerPosition = | |||||
currentChildPageController.position; | |||||
// if (isOperateBody) { | |||||
if (!isOperateBody && | |||||
(outPosition != null) && | |||||
(outPosition.pixels > outPosition.minScrollExtent && | |||||
outPosition.pixels < outPosition.maxScrollExtent)) { | |||||
outPosition.goBallistic(velocity); | |||||
currentInnerPosition.goBallistic(0.0); | |||||
_currentDrag?.dispose(); | |||||
_currentDrag = null; | |||||
return; | |||||
} | |||||
if (isOperateBody && velocity > 0) { | |||||
if (currentInnerPosition.pixels < currentInnerPosition.maxScrollExtent && | |||||
currentInnerPosition.pixels > currentInnerPosition.minScrollExtent) { | |||||
outPosition.goBallistic(0.0); | |||||
currentInnerPosition.goBallistic(velocity); | |||||
} else { | |||||
outPosition?.goBallistic(velocity); | |||||
currentInnerPosition.goBallistic(0.0); | |||||
} | |||||
} else { | |||||
if (currentInnerPosition.pixels < currentInnerPosition.maxScrollExtent) { | |||||
outPosition.goBallistic(0.0); | |||||
currentInnerPosition.goBallistic(velocity); | |||||
} else { | |||||
outPosition?.goBallistic(velocity); | |||||
currentInnerPosition.goBallistic(0.0); | |||||
} | |||||
} | |||||
} | |||||
_currentDrag?.dispose(); | |||||
_currentDrag = null; | |||||
} | |||||
@override | |||||
void goIdle() { | |||||
beginActivity(IdleScrollActivity(this), IdleScrollActivity(this)); | |||||
} | |||||
@override | |||||
double setPixels(double pixels) { | |||||
return 0.0; | |||||
} | |||||
ScrollHoldController hold(VoidCallback holdCancelCallback) { | |||||
beginActivity( | |||||
HoldScrollActivity(delegate: this, onHoldCanceled: holdCancelCallback), | |||||
HoldScrollActivity(delegate: this, onHoldCanceled: holdCancelCallback)); | |||||
return this; | |||||
} | |||||
Drag drag(DragStartDetails details, VoidCallback dragCancelCallback) { | |||||
final ScrollDragController drag = ScrollDragController( | |||||
delegate: this, | |||||
details: details, | |||||
onDragCanceled: dragCancelCallback, | |||||
); | |||||
beginActivity( | |||||
DragScrollActivity(this, drag), DragScrollActivity(this, drag)); | |||||
assert(_currentDrag == null); | |||||
_currentDrag = drag; | |||||
return drag; | |||||
} | |||||
void beginActivity( | |||||
ScrollActivity newOuterActivity, ScrollActivity newInnerActivity) { | |||||
getInnerController().position.beginActivity(newInnerActivity); | |||||
if (isOuterControllerEnable()) { | |||||
getOuterController().position.beginActivity(newOuterActivity); | |||||
} | |||||
_currentDrag?.dispose(); | |||||
_currentDrag = null; | |||||
if ((newOuterActivity == null || !newOuterActivity.isScrolling) && | |||||
(newInnerActivity == null || !newInnerActivity.isScrolling)) { | |||||
updateUserScrollDirection(ScrollDirection.idle); | |||||
} | |||||
} | |||||
ScrollDirection get userScrollDirection => _userScrollDirection; | |||||
ScrollDirection _userScrollDirection = ScrollDirection.idle; | |||||
void updateUserScrollDirection(ScrollDirection value) { | |||||
assert(value != null); | |||||
if (userScrollDirection == value) return; | |||||
_userScrollDirection = value; | |||||
getOuterController().position.didUpdateScrollDirection(value); | |||||
if (isOuterControllerEnable()) { | |||||
getInnerController().position.didUpdateScrollDirection(value); | |||||
} | |||||
} | |||||
} | |||||
const PageScrollPhysics _kPagePhysics = PageScrollPhysics(); | |||||
class PrimaryPageView extends StatefulWidget { | |||||
/// Creates a scrollable list that works page by page from an explicit [List] | |||||
/// of widgets. | |||||
/// | |||||
/// This constructor is appropriate for page views with a small number of | |||||
/// children because constructing the [List] requires doing work for every | |||||
/// child that could possibly be displayed in the page view, instead of just | |||||
/// those children that are actually visible. | |||||
PrimaryPageView({ | |||||
Key key, | |||||
this.scrollDirection = Axis.horizontal, | |||||
this.reverse = false, | |||||
PrimaryPageController controller, | |||||
this.physics, | |||||
this.pageSnapping = true, | |||||
this.onPageChanged, | |||||
this.primary = false, | |||||
List<Widget> children = const <Widget>[], | |||||
this.dragStartBehavior = DragStartBehavior.start, | |||||
}) : childrenDelegate = SliverChildListDelegate(children), | |||||
super(key: key) { | |||||
if (controller == null) { | |||||
this.controller = PrimaryPageController(); | |||||
} else { | |||||
this.controller = controller; | |||||
} | |||||
} | |||||
/// Creates a scrollable list that works page by page using widgets that are | |||||
/// created on demand. | |||||
///delta | |||||
/// This constructor is appropriate for page views with a large (or infinite) | |||||
/// number of children because the builder is called only for those children | |||||
/// that are actually visible. | |||||
/// | |||||
/// Providing a non-null [itemCount] lets the [PrimaryPageView] compute the maximum | |||||
/// scroll extent. | |||||
/// | |||||
/// [itemBuilder] will be called only with indices greater than or equal to | |||||
/// zero and less than [itemCount]. | |||||
/// | |||||
/// [PrimaryPageView.builder] by default does not support child reordering. If | |||||
/// you are planning to change child order at a later time, consider using | |||||
/// [PrimaryPageView] or [PrimaryPageView.custom]. | |||||
PrimaryPageView.builder({ | |||||
Key key, | |||||
this.scrollDirection = Axis.horizontal, | |||||
this.reverse = false, | |||||
PrimaryPageController controller, | |||||
this.physics, | |||||
this.pageSnapping = true, | |||||
this.onPageChanged, | |||||
@required IndexedWidgetBuilder itemBuilder, | |||||
int itemCount, | |||||
this.primary = false, | |||||
this.dragStartBehavior = DragStartBehavior.start, | |||||
}) : childrenDelegate = | |||||
SliverChildBuilderDelegate(itemBuilder, childCount: itemCount), | |||||
super(key: key) { | |||||
if (controller == null) { | |||||
this.controller = PrimaryPageController(); | |||||
} else { | |||||
this.controller = controller; | |||||
} | |||||
} | |||||
PrimaryPageView.custom({ | |||||
Key key, | |||||
this.scrollDirection = Axis.horizontal, | |||||
this.reverse = false, | |||||
PrimaryPageController controller, | |||||
this.physics, | |||||
this.pageSnapping = true, | |||||
this.onPageChanged, | |||||
@required this.childrenDelegate, | |||||
this.primary = false, | |||||
this.dragStartBehavior = DragStartBehavior.start, | |||||
}) : assert(childrenDelegate != null), | |||||
super(key: key) { | |||||
if (controller == null) { | |||||
this.controller = PrimaryPageController(); | |||||
} else { | |||||
this.controller = controller; | |||||
} | |||||
} | |||||
/// The axis along which the page view scrolls. | |||||
/// | |||||
/// Defaults to [Axis.horizontal]. | |||||
final Axis scrollDirection; | |||||
/// Whether the page view scrolls in the reading direction. | |||||
/// | |||||
/// For example, if the reading direction is left-to-right and | |||||
/// [scrollDirection] is [Axis.horizontal], then the page view scrolls from | |||||
/// left to right when [reverse] is false and from right to left when | |||||
/// [reverse] is true. | |||||
/// | |||||
/// Similarly, if [scrollDirection] is [Axis.vertical], then the page view | |||||
/// scrolls from top to bottom when [reverse] is false and from bottom to top | |||||
/// when [reverse] is true. | |||||
/// | |||||
/// Defaults to false. | |||||
final bool reverse; | |||||
/// An object that can be used to control the position to which this page | |||||
/// view is scrolled. | |||||
PrimaryPageController controller; | |||||
/// How the page view should respond to user input. | |||||
/// | |||||
/// For example, determines how the page view continues to animate after the | |||||
/// user stops dragging the page view. | |||||
/// | |||||
/// The physics are modified to snap to page boundaries using | |||||
/// [PageScrollPhysics] prior to being used. | |||||
/// | |||||
/// Defaults to matching platform conventions. | |||||
final ScrollPhysics physics; | |||||
/// Set to false to disable page snapping, useful for custom scroll behavior. | |||||
final bool pageSnapping; | |||||
/// Called whenever the page in the center of the viewport changes. | |||||
final ValueChanged<int> onPageChanged; | |||||
/// A delegate that provides the children for the [PrimaryPageView]. | |||||
/// | |||||
/// The [PrimaryPageView.custom] constructor lets you specify this delegate | |||||
/// explicitly. The [PrimaryPageView] and [PrimaryPageView.builder] constructors create a | |||||
/// [childrenDelegate] that wraps the given [List] and [IndexedWidgetBuilder], | |||||
/// respectively. | |||||
final SliverChildDelegate childrenDelegate; | |||||
/// {@macro flutter.widgets.scrollable.dragStartBehavior} | |||||
final DragStartBehavior dragStartBehavior; | |||||
final bool primary; | |||||
@override | |||||
_PageViewState createState() => _PageViewState(); | |||||
} | |||||
class _PageViewState extends State<PrimaryPageView> { | |||||
int _lastReportedPage = 0; | |||||
@override | |||||
void initState() { | |||||
super.initState(); | |||||
_lastReportedPage = widget.controller.initialPage; | |||||
} | |||||
@override | |||||
void didChangeDependencies() { | |||||
super.didChangeDependencies(); | |||||
} | |||||
AxisDirection _getDirection(BuildContext context) { | |||||
switch (widget.scrollDirection) { | |||||
case Axis.horizontal: | |||||
assert(debugCheckHasDirectionality(context)); | |||||
final TextDirection textDirection = Directionality.of(context); | |||||
final AxisDirection axisDirection = | |||||
textDirectionToAxisDirection(textDirection); | |||||
return widget.reverse | |||||
? flipAxisDirection(axisDirection) | |||||
: axisDirection; | |||||
case Axis.vertical: | |||||
return widget.reverse ? AxisDirection.up : AxisDirection.down; | |||||
} | |||||
return null; | |||||
} | |||||
@override | |||||
Widget build(BuildContext context) { | |||||
final AxisDirection axisDirection = _getDirection(context); | |||||
final ScrollPhysics physics = widget.pageSnapping | |||||
? _kPagePhysics.applyTo(widget.physics) | |||||
: widget.physics; | |||||
final ScrollController scrollController = widget.primary | |||||
? PrimaryScrollController.of(context) | |||||
: widget.controller; | |||||
if (widget.primary && scrollController is PrimaryPageController) { | |||||
scrollController.initialPage = _lastReportedPage; | |||||
PrimaryPageCoordinator(widget.controller, scrollController); | |||||
} | |||||
return NotificationListener<ScrollNotification>( | |||||
onNotification: (ScrollNotification notification) { | |||||
if (notification.depth == 0 && | |||||
widget.onPageChanged != null && | |||||
notification is ScrollUpdateNotification) { | |||||
final PageMetrics metrics = notification.metrics; | |||||
final int currentPage = metrics.page.round(); | |||||
if (currentPage != _lastReportedPage) { | |||||
_lastReportedPage = currentPage; | |||||
widget.onPageChanged(currentPage); | |||||
} | |||||
} | |||||
return false; | |||||
}, | |||||
child: Scrollable( | |||||
/// magic code,魔法代码勿动……这个key很重要 | |||||
/// 如果PrimaryPageView下面还有多个同级PrimaryPageView, | |||||
/// 那么竟然会导致父PrimaryPageView识别为子PrimaryPageView | |||||
/// 进而在didUpdateWidget中解绑父PrimaryPageView中controller绑定的position | |||||
/// 并将其赋予给子PrimaryPageView的controller | |||||
/// 这样就导致父PrimaryPageView就这么神奇的丢失了自己的position…… | |||||
/// 进而无法触发任何父PrimaryPageView的滑动事件 | |||||
/// 不知道是我的问题还是flutter的问题 | |||||
/// 不过既然知道原因了 | |||||
/// 用key打个补丁,加上个身份证就好了……有空研究下这个神奇的问题 | |||||
key: Key(widget.controller.toString()), | |||||
dragStartBehavior: widget.dragStartBehavior, | |||||
axisDirection: axisDirection, | |||||
controller: widget.controller, | |||||
physics: physics, | |||||
viewportBuilder: (BuildContext context, ViewportOffset position) { | |||||
return Viewport( | |||||
cacheExtent: 0.0, | |||||
axisDirection: axisDirection, | |||||
offset: position, | |||||
slivers: <Widget>[ | |||||
PrimaryScrollController( | |||||
controller: widget.controller, | |||||
child: SliverFillViewport( | |||||
viewportFraction: widget.controller.viewportFraction, | |||||
delegate: widget.childrenDelegate, | |||||
)), | |||||
], | |||||
); | |||||
}, | |||||
), | |||||
); | |||||
} | |||||
@override | |||||
void debugFillProperties(DiagnosticPropertiesBuilder description) { | |||||
super.debugFillProperties(description); | |||||
description | |||||
.add(EnumProperty<Axis>('scrollDirection', widget.scrollDirection)); | |||||
description.add( | |||||
FlagProperty('reverse', value: widget.reverse, ifTrue: 'reversed')); | |||||
description.add(DiagnosticsProperty<PrimaryPageController>( | |||||
'controller', widget.controller, | |||||
showName: false)); | |||||
description.add(DiagnosticsProperty<ScrollPhysics>( | |||||
'physics', widget.physics, | |||||
showName: false)); | |||||
description.add(FlagProperty('pageSnapping', | |||||
value: widget.pageSnapping, ifFalse: 'snapping disabled')); | |||||
} | |||||
} |
@@ -34,8 +34,14 @@ class _ShareAlertState extends State<ShareAlert> { | |||||
@override | @override | ||||
void initState() { | void initState() { | ||||
NetUtil.request('/api/v1/mod/${widget.skipIdentifier}', method: NetMethod.GET, onCache: (data) { | NetUtil.request('/api/v1/mod/${widget.skipIdentifier}', method: NetMethod.GET, onCache: (data) { | ||||
_parseData(data); | |||||
// try{ | |||||
// _parseData(data); | |||||
// }catch(e){ | |||||
// print(e); | |||||
// } | |||||
}, onSuccess: (data) { | }, onSuccess: (data) { | ||||
print(data); | |||||
_parseData(data); | _parseData(data); | ||||
}, onError: (err) {}); | }, onError: (err) {}); | ||||
@@ -247,9 +253,20 @@ class _ShareAlertContentState extends State<_ShareAlertContent> { | |||||
); | ); | ||||
} | } | ||||
} else { | } else { | ||||
var type=SSDKContentTypes.auto; | |||||
if(widget?.model?.image?.first!=null&&widget.model?.url!=null){ | |||||
type=SSDKContentTypes.webpage; | |||||
}else if(widget?.model?.image?.first!=null){ | |||||
type=SSDKContentTypes.image; | |||||
}else if(widget?.model?.title!=null||widget.model?.content!=null){ | |||||
type=SSDKContentTypes.text; | |||||
} | |||||
params = SSDKMap() | params = SSDKMap() | ||||
..setGeneral( | ..setGeneral( | ||||
widget.model?.title ?? '', | |||||
widget.model?.title ?? '123', | |||||
widget.model?.content ?? '', | widget.model?.content ?? '', | ||||
Platform.isIOS ? widget.model.image : null, | Platform.isIOS ? widget.model.image : null, | ||||
Platform.isAndroid ? widget?.model?.image?.first : null, | Platform.isAndroid ? widget?.model?.image?.first : null, | ||||
@@ -259,7 +276,7 @@ class _ShareAlertContentState extends State<_ShareAlertContent> { | |||||
null, | null, | ||||
null, | null, | ||||
null, | null, | ||||
SSDKContentTypes.auto, | |||||
type, | |||||
); | ); | ||||
} | } | ||||
SharesdkPlugin.share(plateform, params, (SSDKResponseState state, Map userdata, Map contentEntity, SSDKError error) { | SharesdkPlugin.share(plateform, params, (SSDKResponseState state, Map userdata, Map contentEntity, SSDKError error) { | ||||