SteamCloudGame/lib/tools/home/my_home_page.dart
2024-12-29 14:27:28 +08:00

527 lines
20 KiB
Dart

import 'dart:async';
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:game/common/EventBusUtil.dart';
import 'package:game/dialog/sign_dialog.dart';
import 'package:game/network/NetworkConfig.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../beans/epg_bean.dart';
import '../../beans/home_info_bean.dart';
import '../../beans/home_ranking_bean.dart';
import '../../beans/sign_bean.dart';
import '../../common/func.dart';
import '../game/game_info_page.dart';
import '../me/set/agreement_page.dart';
import 'home_ranking_page.dart';
import 'home_recommend_page.dart';
import 'my_home_model.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<EpgBean> bannerList = [];
List<HomeInfoBean> homeInfoList = [];
int currentBannerIndex = 0; //banner下标
int pageIndex = 0; // 0推荐 1历史
late StreamSubscription subscription;
final MyHomeModel _viewModel = MyHomeModel();
List<HomeRankingBean> rankingList = [];
late SignBean signBean;
int unreadNum = 0;
@override
void initState() {
// TODO: implement initState
super.initState();
subscription = _viewModel.streamController.stream.listen((event) {
String code = event['code'];
if (code.isNotEmpty) {
switch (code) {
case "getHomeInfo":
EasyLoading.dismiss();
List<HomeInfoBean> data = event['data'];
for (int i = 0; i < data.length; i++) {
///banner数据
if (data[i].categoryName == "Banner") {
bannerList = data[i].epgList!;
print("bannerList==${bannerList.length}");
} else {
homeInfoList.add(data[i]);
}
}
break;
case "getGameRankingList": //排行
rankingList = event['data'];
break;
case "getSevenSignList": //七天签到
signBean = event['data'];
if (!signBean.isSign!) {
FunctionUtil.popDialog2(
context,
SignDialog(
list: signBean.list!,
onTap: () {
FunctionUtil.loading();
_viewModel.sevenSignToday();
},
));
}
break;
case "sevenSignToday": //签到
EasyLoading.showToast(event['data']);
EventBusUtil.fire(RefreshUserdata());
_viewModel.getSevenSignList();
_viewModel.getUserInfo();
break;
case "getUserMessageNotReadCount": //是否有新消息
unreadNum = event['data'];
break;
}
setState(() {});
}
});
FunctionUtil.loading();
_viewModel.getHomeInfo();
_viewModel.getGameRankingList();
if (NetworkConfig.token != "") {
if (!NetworkConfig.isChecking) {
_viewModel.getSevenSignList();
}
_viewModel.getUserMessageNotReadCount();
_viewModel.getUserInfo();
}
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
subscription.cancel();
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final h387 = size.width / 0.9302325581395;
final h88 = size.width / 4.090909090909091;
final l15 = size.width / 24;
final s21 = size.width / 17.14285714285714;
final b21 = size.width / 17.14285714285714;
final r14 = size.width / 25.71428571428571;
final h50 = size.width / 7.2;
final w166 = size.width / 2.168674698795181;
final h45 = size.width / 8;
final h40 = size.width / 9;
final c19 = size.width / 18.94736842105263;
final h36 = size.width / 10;
final w16 = size.width / 22.5;
final l25 = size.width / 14.4;
final l17 = size.width / 21.17647058823529;
final t13 = size.width / 27.692307692307;
final t9 = size.width / 40;
final w4 = size.width / 90;
final l7 = size.width / 51.428571428571;
final c10 = size.width / 36;
final s13 = size.width / 27.692307692307;
final s14 = size.width / 25.714285714285;
final c4 = size.width / 90;
final l11 = size.width / 32.727272727272;
final t8 = size.width / 45;
final r7 = size.width / 51.428571428571;
return Scaffold(
backgroundColor: const Color(0xFF17181A),
body: Stack(
children: [
SingleChildScrollView(
child: Column(
children: [
SizedBox(
width: size.width,
height: h387,
child: Stack(
children: [
///banner
CarouselSlider(
options: CarouselOptions(
height: h387,
autoPlay: true,
viewportFraction: 1,
onPageChanged: (index, _) {
setState(() {
currentBannerIndex = index;
});
}),
items: _bannerItem(h387),
),
///banner标题
Positioned(
bottom: 0,
child: Container(
width: size.width,
height: h88,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0x0017181A),
Color(0xFF17181A),
],
),
),
child: Stack(
children: [
Positioned(
left: l15,
top: t13,
child: bannerList.isNotEmpty
? Text(
"${bannerList[currentBannerIndex].title}",
style: TextStyle(color: Colors.white, fontSize: s21),
)
: Container()),
Positioned(
left: l15,
bottom: b21,
child: bannerList.isNotEmpty
? Text(
"${bannerList[currentBannerIndex].subTitle}",
style: TextStyle(color: Colors.white, fontSize: s13),
)
: Container()),
///banner指示器
Positioned(
top: t9,
right: r14,
child: Row(
children: List.generate(
bannerList.length,
(index) => Container(
width: w4,
height: w4,
margin: EdgeInsets.only(left: l7),
decoration: BoxDecoration(
color: Color(currentBannerIndex == index ? 0xFFFFFFFF : 0x99FFFFFF),
borderRadius: BorderRadius.all(Radius.circular(c10))),
)),
))
],
),
)),
],
),
),
///推荐 - 游玩历史
Container(
width: size.width,
height: h50,
margin: EdgeInsets.only(left: r14, right: r14),
child: Stack(
children: [
Container(
height: h45,
decoration: BoxDecoration(
border: Border.all(color: Color(0xFF3B3C3F)),
borderRadius: BorderRadius.all(Radius.circular(c4)),
),
),
Row(
children: [
GestureDetector(
onTap: () {
setState(() {
pageIndex = 0;
});
},
child: Container(
width: w166,
height: h45,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Color(pageIndex == 0 ? 0xFF0C0C0C : 0x00FFFFFF),
border: Border.all(color: Color(pageIndex == 0 ? 0xFF9C9C9C : 0x00FFFFFF), width: 1),
borderRadius: const BorderRadius.all(Radius.circular(4))),
child: ShaderMask(
shaderCallback: (Rect bounds) {
return LinearGradient(
colors: pageIndex == 0
? [
const Color(0xFF22F1F5),
const Color(0xFF22F1F5),
const Color(0xFF7A6EFA),
const Color(0xFF7A6EFA),
]
: [
const Color(0xFF909090),
const Color(0xFF909090),
],
).createShader(bounds);
},
blendMode: BlendMode.srcATop,
child: Text(
'推荐',
style: TextStyle(fontSize: s14),
),
),
),
),
GestureDetector(
onTap: () {
if (NetworkConfig.token == "") {
Navigator.pushNamed(context, "/LoginPage");
return;
}
setState(() {
pageIndex = 1;
});
},
child: Container(
width: w166,
height: h45,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Color(pageIndex == 1 ? 0xFF0C0C0C : 0x00FFFFFF),
border: Border.all(color: Color(pageIndex == 1 ? 0xFF9C9C9C : 0x00FFFFFF), width: 1),
borderRadius: BorderRadius.all(Radius.circular(c4))),
child: ShaderMask(
shaderCallback: (Rect bounds) {
return LinearGradient(
colors: pageIndex == 1
? [
const Color(0xFF22F1F5),
const Color(0xFF22F1F5),
const Color(0xFF7A6EFA),
const Color(0xFF7A6EFA),
]
: [
const Color(0xFF909090),
const Color(0xFF909090),
],
).createShader(bounds);
},
blendMode: BlendMode.srcATop,
child: Text(
'游戏排行',
style: TextStyle(fontSize: s14),
),
),
),
),
],
),
],
),
),
Container(
child: pageIndex == 0
//推荐
? Column(
children: List.generate(homeInfoList.length, (index) => HomeRecommendPage(UniqueKey(), homeInfoBean: homeInfoList[index])),
)
//游戏排行
: HomeRankingPage(rankingList: rankingList),
),
],
),
),
///顶部栏
Positioned(
top: MediaQuery.of(context).padding.top,
child: SizedBox(
width: size.width,
height: h40,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
///搜索
Expanded(
child: GestureDetector(
onTap: () {
if (NetworkConfig.token == "") {
Navigator.pushNamed(context, "/LoginPage");
return;
}
Navigator.pushNamed(context, "/SearchPage");
},
child: Container(
margin: EdgeInsets.only(left: s14, right: l25),
child: ClipRRect(
borderRadius: BorderRadius.circular(c19),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 5,
sigmaY: 5,
),
child: Container(
height: h36,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: l11),
decoration: BoxDecoration(
color: const Color(0x73FFFFFF),
borderRadius: BorderRadius.all(Radius.circular(c19)),
),
child: Image(width: w16, height: w16, image: AssetImage('assets/images/ic_search.png')),
),
),
),
),
),
),
///消息
!NetworkConfig.isChecking
? GestureDetector(
onTap: () {
if (NetworkConfig.token == "") {
Navigator.pushNamed(context, "/LoginPage");
return;
}
Navigator.pushNamed(context, "/MessageCenterPage").then((value) {
_viewModel.getUserMessageNotReadCount();
});
},
child: Container(
margin: EdgeInsets.only(right: s14),
child: ClipRRect(
borderRadius: BorderRadius.circular(c19),
child: Container(
width: h36,
height: h36,
decoration: const BoxDecoration(color: Color(0x73FFFFFF)),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 5,
sigmaY: 5,
),
child: Stack(
alignment: Alignment.center,
children: [
Image(
width: l17,
height: s14,
image: const AssetImage('assets/images/ic_message.png'),
),
Positioned(
top: t8,
right: r7,
child: unreadNum > 0
? Container(
width: c4,
height: c4,
decoration:
const BoxDecoration(color: Colors.red, borderRadius: BorderRadius.all(Radius.circular(10))),
)
: Container())
],
),
),
),
),
),
)
: Container(),
],
),
)),
],
),
);
}
_bannerItem(h387) {
return bannerList.map((value) {
return Builder(builder: (BuildContext context) {
return GestureDetector(
onTap: () {
_jumpToPage(value);
},
child: SizedBox(
height: h387,
child: CachedNetworkImage(
width: MediaQuery.of(context).size.width,
height: h387,
imageUrl: '${value.imageUrl}',
errorWidget: (context, url, error) => const Icon(Icons.error),
),
),
);
});
}).toList();
}
Future<void> _launchUrl(url) async {
if (!await launchUrl(url)) {
throw Exception('Could not launch $url');
}
}
///跳转页面
_jumpToPage(EpgBean value) {
if (NetworkConfig.token == "") {
Navigator.pushNamed(context, "/LoginPage");
return;
}
switch (value.resType) {
case 1: //游戏详情
Navigator.push(
context,
MaterialPageRoute(
//导航打开新视图
builder: (context) => GameInfoPage(
gameId: "${value.resId}",
),
));
break;
case 2: //app页面
switch (value.resId) {
case "Shop": //商城
EventBusUtil.fire(TabSwitch(2));
break;
case "Task": //任务中心
break;
}
break;
case 3: //内部H5
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AgreementPage(
title: "活动",
url: "${value.resId}",
)),
);
break;
case 4: //外部H5
_launchUrl(Uri.parse('${value.resId}'));
break;
}
}
}