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 createState() => _GalleryPageState(); } class _GalleryPageState extends State with AutomaticKeepAliveClientMixin, SingleTickerProviderStateMixin { @override bool get wantKeepAlive => true; StreamSubscription? subscription; final GalleryModel _viewModel = GalleryModel(); final ScrollController _scrollController = ScrollController(); GlobalKey loginDialogKey = GlobalKey(); //登录弹框key List galleryList = []; int pageIndex = 1; int pageSize = 30; List popList = []; LevitatingBallBean? levitatingBallBean; //动画 AnimationController? _controller; Animation? _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 _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 map = {"googleLogin": "googleLogin"}; invokeNativeMethod("googleLogin", map); break; } }, ), "LoginDialog", canceled: true))) ..show(context); } // 获取原生的值 invokeNativeMethod(String method, Map map) async { dynamic args; try { args = await Global.method.invokeMethod(method, map); } on PlatformException catch (e) {} } }