123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532 |
- import 'dart:io';
- import 'dart:math';
- import 'package:cached_network_image/cached_network_image.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
- import 'package:get_it/get_it.dart';
- import 'package:sport/application.dart';
- import 'package:sport/bean/game.dart';
- import 'package:sport/pages/game/game_detail.dart';
- import 'package:sport/pages/game/game_guide.dart';
- import 'package:sport/pages/game/game_info.dart';
- import 'package:sport/provider/bluetooth.dart';
- import 'package:sport/provider/game_model.dart';
- import 'package:sport/router/navigator_util.dart';
- import 'package:sport/services/api/inject_api.dart';
- import 'package:sport/services/app_subscription_state.dart';
- import 'package:sport/services/inject_route_aware.dart';
- import 'package:sport/widgets/appbar.dart';
- import 'package:sport/widgets/dialog/ble_wait_dialog.dart';
- import 'package:sport/widgets/image.dart';
- import 'package:umeng_common_sdk/umeng_common_sdk.dart';
- import 'package:wakelock/wakelock.dart';
- class SportListPage extends StatefulWidget {
- final int index;
- final int runUserCount;
- final List<GameInfoData> games;
- SportListPage({this.index = 0, this.runUserCount = 0, required this.games});
- @override
- State<StatefulWidget> createState() => _PageState();
- }
- class _PageState extends State<SportListPage> with InjectApi, SubscriptionState, InjectRouteAware, WidgetsBindingObserver {
- List<GameInfoData> _games = [];
- late PageController _pageController;
- late Bluetooth _bluetooth;
- late GameModel _gameModel;
- late Function() gameModeListener;
- GameInfoData? game;
- int gameIndex = 0;
- bool gameMode = false;
- bool gamePlaying = false;
- @override
- void initState() {
- super.initState();
- WidgetsBinding.instance?.addObserver(this);
- _gameModel = GetIt.I<GameModel>();
- _gameModel.noCheck = true;
- _bluetooth = GetIt.I<Bluetooth>();
- _bluetooth.h5gameRNotifier.addListener(gameModeListener = () {
- gameMode = _bluetooth.h5gameRNotifier.value;
- });
- addSubscription(_bluetooth.sdkCmdStream.listen((event) {
- if (gameMode && !gamePlaying) {
- int cmd = event;
- if (cmd > -1) {
- print("sdk -- cmd $cmd");
- if (cmd == 3) {
- _previous();
- }
- if (cmd == 4) {
- _next();
- }
- if (cmd == 6) {
- _back();
- _bluetooth.vibrate(200, leftOrRight: 1);
- }
- if (cmd == 5) {
- _ok();
- _bluetooth.vibrate(200, leftOrRight: 2);
- }
- }
- }
- }));
- WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
- _checkInstall();
- });
- }
- @override
- void dispose() {
- WidgetsBinding.instance?.removeObserver(this);
- _gameModel.noCheck = false;
- _bluetooth.setupGameMode4h5(false);
- _bluetooth.h5gameRNotifier.removeListener(gameModeListener);
- gameMode = false;
- Wakelock.disable();
- super.dispose();
- // horizontal.value = false;
- // horizontal.dispose();
- }
- @override
- void didChangeAppLifecycleState(AppLifecycleState state) {
- super.didChangeAppLifecycleState(state);
- switch (state) {
- case AppLifecycleState.resumed:
- if (game?.h5 == 0) {
- _bluetooth.gameInit(game?.id ?? 0);
- gamePlaying = false;
- if(gameMode == true)
- showWaitDialog(context);
- }
- Stream.periodic(const Duration(seconds: 2)).take(5).forEach((element) {
- if (mounted) {
- _bluetooth.setupGameMode4h5(gameMode);
- }
- });
- break;
- case AppLifecycleState.paused:
- // if (mounted) {
- // _bluetooth.setupGameMode4h5(false);
- // }
- break;
- default:
- break;
- }
- }
- @override
- void didPop() {
- gamePlaying = false;
- }
- @override
- void didPopNext() {
- gamePlaying = false;
- }
- @override
- void didPushNext() {
- gamePlaying = true;
- }
- _checkInstall() async {
- List<GameInfoData> games = widget.games.isNotEmpty == true ? List.from(widget.games) : (await api.getGameAll()).results;
- for (var i = 0; i < games.length; i++) {
- games[i].isLocal = await isInstalled(games[i]) == 0;
- }
- games.sort((a, b) => a.isLocal == true ? -1 : 1);
- setState(() {
- _games = games;
- });
- }
- _back() {
- Navigator.pop(context, false);
- }
- _ok() {
- if (_games.isNotEmpty == true && gamePlaying != true && appLifecycleState == AppLifecycleState.resumed) {
- gamePlaying = true;
- // _bluetooth.setupGameMode4h5(gameMode = true);
- _gameModel.gameCount++;
- game = _games[gameIndex];
- startGame(context, game, launch4GameCenter: true).then((value) => gamePlaying = false);
- UmengCommonSdk.onEvent("game_start_sport_list", {"id": "${game?.id}"});
- }
- }
- _previous() {
- setState(() {
- gameIndex = --gameIndex % _games.length;
- _switchPage(gameIndex);
- });
- }
- _next() {
- setState(() {
- gameIndex = ++gameIndex % _games.length;
- _switchPage(gameIndex);
- });
- }
- _switchPage(int index) {
- if (!mounted) return;
- int page = _pageController.page?.toInt() ?? 0;
- int currentPage = index ~/ 10;
- if (currentPage != page) {
- _pageController.animateToPage(currentPage, duration: Duration(milliseconds: 500), curve: Curves.linear);
- }
- }
- @override
- Widget build(BuildContext context) {
- final _padding = const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0);
- List<GameInfoData> games = _games;
- return OrientationBuilder(
- builder: (BuildContext context, Orientation orientation) {
- final bool landscape = orientation == Orientation.landscape;
- return Scaffold(
- backgroundColor: landscape ? Colors.black : Colors.black.withOpacity(0.9),
- appBar: AppBar(
- automaticallyImplyLeading: false,
- centerTitle: false,
- titleSpacing: landscape ? 50 : 16,
- systemOverlayStyle: SystemUiOverlayStyle.light,
- backgroundColor: Colors.transparent,
- title: Row(
- children: [
- Text(
- "运动列表",
- style: titleStyle.copyWith(color: Colors.white),
- ),
- const SizedBox(
- width: 20.0,
- ),
- TextButton(
- onPressed: () {
- if (landscape) {
- SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
- _bluetooth.setupGameMode4h5(gameMode = false);
- } else {
- SystemChrome.setPreferredOrientations(Platform.isIOS ? [DeviceOrientation.landscapeRight] : [DeviceOrientation.landscapeLeft]);
- _bluetooth.setupGameMode4h5(gameMode = true);
- }
- },
- child: Row(
- children: [
- Row(children: [
- Image.asset(
- landscape ? "lib/assets/img/icon_pop_vertical_screen.png" : "lib/assets/img/icon_pop_horizontal_screen.png",
- height: 20.0,
- ),
- const SizedBox(
- width: 8.0,
- ),
- Text(
- landscape ? "竖屏切换" : "横屏切换",
- style: Theme.of(context).textTheme.headline6!.copyWith(color: Colors.white),
- )
- ]),
- ],
- )),
- ],
- ),
- actions: [
- landscape ? InkWell(
- onTap: _back,
- child: Padding(
- padding: const EdgeInsets.fromLTRB(8.0,5.0,12.0, 5.0),
- child: Row(
- children: [
- arrowBackShoe(),
- Text(
- "左踮脚 · 返回",
- style: Theme.of(context).textTheme.subtitle1?.copyWith(color: Colors.white),
- )
- ],
- ),
- ),
- ):IconButton(
- icon: Image.asset(
- "lib/assets/img/btn_close_white.png",
- height: 20.0,
- ),
- onPressed: () =>_back())
- ],
- ),
- body: landscape
- ? Column(
- children: [
- Expanded(
- child: PageView.builder(
- controller: _pageController = PageController(initialPage: gameIndex ~/ 10),
- scrollDirection: Axis.vertical,
- itemCount: ((games.length - 1) ~/ 10) + 1,
- itemBuilder: (context, index) {
- return Padding(
- padding: const EdgeInsets.symmetric(horizontal: 30.0, vertical: 12.0),
- child: LayoutBuilder(
- builder: (BuildContext context, BoxConstraints constraints) {
- double width = constraints.biggest.width;
- double height = constraints.biggest.height;
- double mainAxisSpacing = 12.0;
- double crossAxisSpacing = 10.0;
- int crossAxisCount = 5;
- double boxWidth = width / 5 - crossAxisSpacing / 4;
- double boxHeight = (height / 2.0) - mainAxisSpacing;
- return AlignedGridView.count(
- crossAxisCount: crossAxisCount,
- shrinkWrap: true,
- physics: NeverScrollableScrollPhysics(),
- itemCount: min(10, games.length - index * 10),
- crossAxisSpacing: 10.0,
- mainAxisSpacing: mainAxisSpacing,
- itemBuilder: (context, i) {
- int _index = index * 10 + i;
- GameInfoData e = games[_index];
- return InkWell(
- onTap: () {
- setState(() {
- gameIndex = _index;
- _ok();
- });
- },
- child: Container(
- width: boxWidth,
- height: boxHeight,
- alignment: Alignment.center,
- child: Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- AnimatedContainer(
- duration: Duration(milliseconds: 300),
- width: min(boxWidth, boxHeight) * (_index == gameIndex ? .7 : .6),
- height: min(boxWidth, boxHeight) * (_index == gameIndex ? .7 : .6),
- decoration: BoxDecoration(
- image: DecorationImage(
- image: CachedNetworkImageProvider(
- "${e.cover}",
- ),
- fit: BoxFit.cover),
- borderRadius: BorderRadius.circular(10.0),
- border: Border.all(width: 4, color: _index == gameIndex ? Theme.of(context).colorScheme.secondary : Colors.transparent)),
- ),
- const SizedBox(
- height: 8.0,
- ),
- Text(
- "${e.name}",
- maxLines: 1,
- style: Theme.of(context).textTheme.subtitle1!.copyWith(color: _index == gameIndex ? Theme.of(context).colorScheme.secondary : Colors.white),
- )
- ],
- ),
- ),
- );
- });
- },
- ),
- );
- }),
- ),
- Container(
- color: Colors.white.withOpacity(.1),
- padding: const EdgeInsets.symmetric(vertical: 8.0),
- child: Center(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- Row(
- children: [
- Row(children: [
- Image.asset(
- "lib/assets/img/gamepop_leftarrow_notes.png",
- height: 20.0,
- ),
- const SizedBox(
- width: 8.0,
- ),
- Text(
- "左踏 · 上一个",
- style: Theme.of(context).textTheme.headline6!,
- )
- ]),
- ],
- ),
- Row(
- children: [
- Row(children: [
- Image.asset(
- "lib/assets/img/gamepop_rihgtarrow_notes.png",
- height: 20.0,
- ),
- const SizedBox(
- width: 8.0,
- ),
- Text(
- "右踏 · 下一个",
- style: Theme.of(context).textTheme.headline6!,
- )
- ]),
- ],
- ),
- Row(
- children: [
- Row(children: [
- Image.asset(
- "lib/assets/img/gamepop_icon_right_notes.png",
- height: 20.0,
- ),
- const SizedBox(
- width: 8.0,
- ),
- Text(
- "右踮脚 · 确认",
- style: Theme.of(context).textTheme.headline6!,
- )
- ]),
- ],
- ),
- ],
- ),
- ),
- )
- ],
- )
- : CustomScrollView(
- slivers: [
- SliverToBoxAdapter(
- child: InkWell(
- onTap: () {
- NavigatorUtil.goPage(
- context,
- (context) => GameGuide(
- game: GameInfoData(),
- base: true,
- launch4GameCenter: true,
- detailGuide: true,
- ));
- },
- child: Container(
- margin: _padding,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(10.0),
- color: Colors.white,
- ),
- padding: const EdgeInsets.symmetric(horizontal: 14.0, vertical: 15.0),
- child: Row(
- children: [
- Image.asset(
- "lib/assets/img/gamepop_icon_right_notes_black.png",
- height: 20.0,
- ),
- Expanded(
- child: Container(
- margin: const EdgeInsets.only(left: 12.0),
- child: Text(
- "游戏通用操作教程",
- style: Theme.of(context).textTheme.subtitle1,
- ),
- ),
- ),
- arrowRight()
- ],
- )),
- ),
- ),
- for (var e in games)
- SliverToBoxAdapter(
- child: Padding(
- padding: _padding,
- child: GestureDetector(
- onTap: () => NavigatorUtil.goPage(context, (context) => GameDetailsPage(e)),
- child: Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(10.0),
- color: Colors.white,
- ),
- padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 12.0),
- child: Row(
- children: <Widget>[
- ClipRRect(
- borderRadius: BorderRadius.circular(6.0),
- child: CachedNetworkImage(
- width: 60.0,
- height: 60.0,
- fit: BoxFit.cover,
- imageUrl: "${e.cover}",
- ),
- ),
- const SizedBox(
- width: 12.0,
- ),
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- Text(
- e.name ?? "",
- style: Theme.of(context).textTheme.headline3,
- ),
- const SizedBox(
- height: 8,
- ),
- Row(
- children: [
- Text("${e.playMinute}分钟", style: Theme.of(context).textTheme.bodyText1),
- Container(
- decoration: BoxDecoration(shape: BoxShape.circle, color: const Color(0xff999999)),
- margin: const EdgeInsets.symmetric(horizontal: 4),
- width: 2,
- height: 2,
- ),
- Text("${difficulty[(e.difficulty ?? 0) ~/ 40.0]}", style: Theme.of(context).textTheme.bodyText1),
- ],
- ),
- ],
- ),
- ),
- Container(
- width: 110.0,
- child: StartButtonWidget(
- e,
- (v) {
- setState(() {
- gameIndex = games.indexOf(e);
- _ok();
- });
- },
- height: 35.0,
- textStyle: Theme.of(context).textTheme.subtitle1!.copyWith(color: Colors.white),
- ),
- )
- ],
- ),
- ),
- )),
- )
- ],
- ),
- );
- },
- );
- }
- }
|