419 lines
14 KiB
Dart
419 lines
14 KiB
Dart
import 'dart:async';
|
||
import 'dart:io';
|
||
|
||
import 'package:aiplot/tools/gallery/gallery_model.dart';
|
||
import 'package:cached_network_image/cached_network_image.dart';
|
||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||
|
||
import '../../bean/levitating_ball_bean.dart';
|
||
import '../../bean/popout_bean.dart';
|
||
import '../../bean/user_draw_bean.dart';
|
||
import '../../common/Global.dart';
|
||
import '../../common/dialog_bean.dart';
|
||
import '../../common/dialog_manager.dart';
|
||
import '../../common/dialog_util.dart';
|
||
import '../../common/func.dart';
|
||
import '../../dialog/login_dialog.dart';
|
||
import '../../dialog/newDialog.dart';
|
||
import '../../dialog/new_ball_dialog.dart';
|
||
import '../../dialog/phone_login_dialog.dart';
|
||
import '../../network/NetworkConfig.dart';
|
||
import '../drawdetails/draw_details_page.dart';
|
||
|
||
///画廊
|
||
class GalleryPage extends StatefulWidget {
|
||
int labelId;
|
||
|
||
GalleryPage(this.labelId, {Key? key}) : super(key: key);
|
||
|
||
@override
|
||
State<GalleryPage> createState() => _GalleryPageState();
|
||
}
|
||
|
||
class _GalleryPageState extends State<GalleryPage> with AutomaticKeepAliveClientMixin, SingleTickerProviderStateMixin {
|
||
@override
|
||
bool get wantKeepAlive => true;
|
||
|
||
StreamSubscription? subscription;
|
||
final GalleryModel _viewModel = GalleryModel();
|
||
|
||
final ScrollController _scrollController = ScrollController();
|
||
GlobalKey<LoginDialogState> loginDialogKey = GlobalKey(); //登录弹框key
|
||
List<UserDrawBean> galleryList = [];
|
||
int pageIndex = 1;
|
||
int pageSize = 30;
|
||
List<PopoutBean> popList = [];
|
||
LevitatingBallBean? levitatingBallBean;
|
||
|
||
//动画
|
||
AnimationController? _controller;
|
||
Animation<double>? _animation;
|
||
|
||
@override
|
||
void initState() {
|
||
// TODO: implement initState
|
||
super.initState();
|
||
|
||
if (Platform.isIOS) {
|
||
subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
||
// Got a new connectivity status!
|
||
if (result == ConnectivityResult.mobile || result == ConnectivityResult.wifi) {
|
||
setState(() {
|
||
getData();
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
//缩放动画
|
||
_controller = AnimationController(duration: const Duration(milliseconds: 800), vsync: this);
|
||
_animation = Tween(begin: 1.0, end: 1.2).animate(CurvedAnimation(parent: _controller!, curve: Curves.linear))
|
||
..addStatusListener((status) {
|
||
if (status == AnimationStatus.completed) {
|
||
_controller!.reverse();
|
||
} else if (status == AnimationStatus.dismissed) {
|
||
_controller!.forward();
|
||
}
|
||
});
|
||
_controller!.forward();
|
||
|
||
//网络请求回调
|
||
subscription = _viewModel.streamController.stream.listen((newData) {
|
||
String code = newData['code'];
|
||
if (code.isNotEmpty) {
|
||
EasyLoading.dismiss();
|
||
switch (code) {
|
||
case "getGalleryList":
|
||
galleryList.addAll(newData['data']);
|
||
break;
|
||
|
||
case "getPopoutList":
|
||
popList = newData['data'];
|
||
if (popList.length > 0) {
|
||
for (int i = 0; i < popList.length; i++) {
|
||
DialogManager()
|
||
..add(DialogBean(
|
||
createDialogWidget: () => DialogUtil.createTipWidget(
|
||
context,
|
||
newDialog(
|
||
onTap: (PopoutId, PopoutType, text) {
|
||
// ObtainPopoutAwards(PopoutId, PopoutType, text);
|
||
},
|
||
popoutBean: popList[i],
|
||
),
|
||
"Popout" + i.toString(),
|
||
canceled: false)))
|
||
..show(context);
|
||
}
|
||
}
|
||
break;
|
||
case "getLevitatingBall": //悬浮球
|
||
levitatingBallBean = newData['data'];
|
||
if (levitatingBallBean != null) {
|
||
setState(() {});
|
||
}
|
||
break;
|
||
|
||
case "receiveAwardNewUserPackage": //领取悬浮球
|
||
levitatingBallBean = null;
|
||
String message = newData['data'];
|
||
EasyLoading.showToast(message);
|
||
setState(() {});
|
||
break;
|
||
|
||
default:
|
||
String message = newData['data'];
|
||
EasyLoading.showToast(message);
|
||
break;
|
||
}
|
||
}
|
||
setState(() {});
|
||
});
|
||
|
||
//上拉加载
|
||
_scrollController.addListener(() {
|
||
//判断是否滑动到了页面的最底部
|
||
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
|
||
//如果不是最后一页数据,则生成新的数据添加到list里面
|
||
pageIndex++;
|
||
_viewModel.getGalleryList(pageIndex, pageSize, widget.labelId);
|
||
}
|
||
});
|
||
getData();
|
||
}
|
||
|
||
Future getData() async {
|
||
EasyLoading.show(status: 'loading...');
|
||
_viewModel.getGalleryList(pageIndex, pageSize, widget.labelId);
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
// TODO: implement dispose
|
||
subscription?.cancel();
|
||
_controller?.dispose();
|
||
super.dispose();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final size = MediaQuery.of(context).size;
|
||
return Scaffold(
|
||
backgroundColor: Colors.white,
|
||
body: Stack(
|
||
children: [
|
||
galleryList.isNotEmpty
|
||
? Container(
|
||
margin: EdgeInsets.only(top: 5),
|
||
child: SingleChildScrollView(
|
||
controller: _scrollController,
|
||
child: Container(
|
||
padding: EdgeInsets.only(bottom: 20, left: 15, right: 15),
|
||
height: galleryList.length <= 4 ? size.height : null,
|
||
child: MasonryGridView.count(
|
||
crossAxisCount: 2,
|
||
itemCount: galleryList.length,
|
||
itemBuilder: (BuildContext context, int index) {
|
||
return _item(galleryList[index], index);
|
||
},
|
||
// 纵向元素间距
|
||
mainAxisSpacing: 0,
|
||
// 横向元素间距
|
||
crossAxisSpacing: 10,
|
||
physics: const NeverScrollableScrollPhysics(),
|
||
shrinkWrap: true,
|
||
),
|
||
),
|
||
),
|
||
)
|
||
: SingleChildScrollView(
|
||
controller: _scrollController,
|
||
child: Container(
|
||
width: size.width,
|
||
height: size.height,
|
||
),
|
||
),
|
||
levitatingBallBean != null && levitatingBallBean!.Popup != null
|
||
? Positioned(
|
||
right: 5,
|
||
bottom: 100,
|
||
child: GestureDetector(
|
||
onTap: () {
|
||
DialogManager()
|
||
..add(DialogBean(
|
||
createDialogWidget: () => DialogUtil.createTipWidget(
|
||
context,
|
||
NewBallDialog(
|
||
onTap: (PopoutType, text) {
|
||
_viewModel.receiveAwardNewUserPackage();
|
||
},
|
||
popoutBean: levitatingBallBean!.Popup!,
|
||
),
|
||
"NewBallDialog",
|
||
canceled: false)))
|
||
..show(context);
|
||
},
|
||
child: ScaleTransition(
|
||
scale: _animation!,
|
||
child: CachedNetworkImage(
|
||
fit: BoxFit.fitWidth,
|
||
width: 60,
|
||
height: 65,
|
||
imageUrl: levitatingBallBean!.ImageUrl!,
|
||
errorWidget: (context, url, error) => const Image(
|
||
fit: BoxFit.fitWidth,
|
||
width: 60,
|
||
height: 65,
|
||
image: AssetImage('assets/images/btn_cirilibao.webp'),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
)
|
||
: Container(),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
// 下拉刷新
|
||
Future<void> _onRefresh() async {
|
||
// 持续两秒
|
||
await Future.delayed(const Duration(milliseconds: 1500), () {
|
||
pageIndex = 1;
|
||
pageSize = 40;
|
||
galleryList = [];
|
||
_viewModel.getGalleryList(pageIndex, pageSize, widget.labelId);
|
||
// setState(() {});
|
||
});
|
||
}
|
||
|
||
_item(UserDrawBean bean, int index) {
|
||
return GestureDetector(
|
||
onTap: () {},
|
||
child: Column(
|
||
children: [
|
||
///Ai图
|
||
ClipRRect(
|
||
borderRadius: BorderRadius.circular(7),
|
||
child: GestureDetector(
|
||
onTap: () {
|
||
if (NetworkConfig.userId == "") {
|
||
showLoginDialog();
|
||
} else {
|
||
Navigator.push(
|
||
context,
|
||
MaterialPageRoute(
|
||
builder: (context) => DrawDetailsPage(
|
||
false,
|
||
drawId: bean.DrawId.toString(),
|
||
isMyWork: false,
|
||
status: 3,
|
||
),
|
||
));
|
||
}
|
||
},
|
||
child: CachedNetworkImage(
|
||
imageUrl: bean.ImageUrl!,
|
||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||
),
|
||
),
|
||
),
|
||
|
||
// Container(
|
||
// alignment: Alignment.centerLeft,
|
||
// margin: EdgeInsets.only(top: 11),
|
||
// child: Text(
|
||
// bean.Title,
|
||
// maxLines: 1,
|
||
// overflow: TextOverflow.ellipsis,
|
||
// style: TextStyle(color: Colors.black),
|
||
// ),
|
||
// ),
|
||
Container(
|
||
height: 40,
|
||
child: Stack(
|
||
alignment: Alignment.center,
|
||
children: [
|
||
///头像
|
||
Positioned(
|
||
left: 0,
|
||
child: CachedNetworkImage(
|
||
fit: BoxFit.fitHeight,
|
||
width: 18,
|
||
height: 18,
|
||
imageUrl: bean.UserIocn!,
|
||
errorWidget: (context, url, error) => Image(
|
||
fit: BoxFit.fitWidth,
|
||
width: 18,
|
||
height: 18,
|
||
image: AssetImage('assets/images/head.png'),
|
||
),
|
||
),
|
||
),
|
||
Positioned(
|
||
left: 23,
|
||
child: Container(
|
||
width: 80,
|
||
child: Text(
|
||
bean.UserNickName!,
|
||
maxLines: 1,
|
||
overflow: TextOverflow.ellipsis,
|
||
style: TextStyle(color: Colors.black, fontSize: 12),
|
||
),
|
||
),
|
||
),
|
||
|
||
///收藏
|
||
Positioned(
|
||
right: 0,
|
||
child: GestureDetector(
|
||
behavior: HitTestBehavior.opaque,
|
||
onTap: () {
|
||
if (NetworkConfig.userId == "") {
|
||
showLoginDialog();
|
||
} else {
|
||
bean.IsCollect = !bean.IsCollect!;
|
||
if (bean.IsCollect!) {
|
||
bean.CollectNumber = (bean.CollectNumber! + 1);
|
||
} else {
|
||
if (bean.CollectNumber! > 0) {
|
||
bean.CollectNumber = (bean.CollectNumber! - 1);
|
||
}
|
||
}
|
||
setState(() {});
|
||
_viewModel.userDrawCollect(bean.IsCollect!, bean.DrawId.toString());
|
||
}
|
||
},
|
||
child: Container(
|
||
padding: EdgeInsets.all(15),
|
||
child: Row(
|
||
children: [
|
||
Image(
|
||
width: 13,
|
||
height: 12,
|
||
image: bean.IsCollect!
|
||
? const AssetImage('assets/images/ic_collect_s.png')
|
||
: const AssetImage('assets/images/ic_collect.png'),
|
||
),
|
||
Container(
|
||
margin: EdgeInsets.only(left: 5),
|
||
child: Text(
|
||
bean.CollectNumber.toString(),
|
||
style: TextStyle(color: bean.IsCollect! ? Color(0xFFBB72E0) : Colors.black, fontSize: 12),
|
||
),
|
||
)
|
||
],
|
||
),
|
||
)),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
//弹出登录
|
||
showLoginDialog() {
|
||
DialogManager()
|
||
..add(DialogBean(
|
||
dialogPriority: DialogPriority.highClear,
|
||
createDialogWidget: () => DialogUtil.createTipWidget(
|
||
context,
|
||
LoginDialog(
|
||
loginDialogKey,
|
||
onTap: (index) {
|
||
switch (index) {
|
||
case 0:
|
||
if (loginDialogKey.currentState != null) {
|
||
loginDialogKey.currentState!.Pop();
|
||
}
|
||
FunctionUtil.bottomSheetDialog(context, PhoneLoginDialog());
|
||
break;
|
||
case 1: //谷歌登录
|
||
Map<String, String> map = {"googleLogin": "googleLogin"};
|
||
invokeNativeMethod("googleLogin", map);
|
||
break;
|
||
}
|
||
},
|
||
),
|
||
"LoginDialog",
|
||
canceled: true)))
|
||
..show(context);
|
||
}
|
||
|
||
// 获取原生的值
|
||
invokeNativeMethod(String method, Map<String, dynamic> map) async {
|
||
dynamic args;
|
||
try {
|
||
args = await Global.method.invokeMethod(method, map);
|
||
} on PlatformException catch (e) {}
|
||
}
|
||
}
|