sport_history_all_page.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import 'dart:convert';
  2. import 'package:cached_network_image/cached_network_image.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter/painting.dart';
  6. import 'package:flutter_easyrefresh/easy_refresh.dart';
  7. import 'package:sport/bean/game.dart';
  8. import 'package:sport/bean/game_record_sum.dart';
  9. import 'package:sport/bean/sport_detail.dart';
  10. import 'package:sport/constant/ui.dart';
  11. import 'package:sport/pages/game/game_detail.dart';
  12. import 'package:sport/pages/game/index.dart';
  13. import 'package:sport/pages/home/sport_history_page.dart';
  14. import 'package:sport/provider/lib/provider_widget.dart';
  15. import 'package:sport/provider/lib/simple_model.dart';
  16. import 'package:sport/provider/lib/view_state_lifecycle.dart';
  17. import 'package:sport/provider/sport_history_model.dart';
  18. import 'package:sport/router/navigator_util.dart';
  19. import 'package:sport/services/api/inject_api.dart';
  20. import 'package:sport/widgets/appbar.dart';
  21. import 'package:sport/widgets/button_primary.dart';
  22. import 'package:sport/widgets/decoration.dart';
  23. import 'package:sport/widgets/error.dart';
  24. import 'package:sport/widgets/image.dart';
  25. import 'package:sport/widgets/loading.dart';
  26. import 'package:sport/widgets/misc.dart';
  27. import 'package:sport/widgets/space.dart';
  28. class SportHistoryAllPage extends StatefulWidget {
  29. SportHistoryAllPage();
  30. @override
  31. State<StatefulWidget> createState() => _PageState();
  32. }
  33. class _PageState extends ViewStateLifecycle<SportHistoryAllPage, SimpleModel> with InjectApi {
  34. @override
  35. void initState() {
  36. super.initState();
  37. }
  38. @override
  39. Widget build(BuildContext context) {
  40. return Scaffold(
  41. body: ProviderWidget<SimpleModel>(
  42. model: model,
  43. onModelReady: (model) => model.initData(),
  44. builder: (_, model, __) {
  45. return EasyRefresh.builder(
  46. controller: model.refreshController,
  47. enableControlFinishRefresh: true,
  48. enableControlFinishLoad: true,
  49. onRefresh: () => model.refresh(),
  50. onLoad: model.isIdle ? () => model.loadMore() : null,
  51. header: buildClassicalHeader(bgColor: Theme.of(context).scaffoldBackgroundColor),
  52. footer: buildClassicalFooter(),
  53. builder: (context, physics, header, footer) => CustomScrollView(
  54. slivers: <Widget>[
  55. buildSliverAppBar(context, "运动记录", backgroundColor: Theme.of(context).scaffoldBackgroundColor),
  56. if (model.isBusy)
  57. SliverToBoxAdapter(
  58. child: RequestLoadingWidget(),
  59. ),
  60. // if (model.isIdle)
  61. SliverPadding(
  62. padding: const EdgeInsets.symmetric(horizontal: 12.0),
  63. sliver: SliverList(
  64. delegate: SliverChildBuilderDelegate(
  65. (context, index) {
  66. GameRecordSum item = model.list[index];
  67. return GestureDetector(
  68. onTap: () => NavigatorUtil.goPage(context, (context) => SportHistoryPage(item.game)),
  69. child: Container(
  70. margin: index == 0 ?const EdgeInsets.only(top: 0) :const EdgeInsets.only(top: ui_padding),
  71. decoration: circular(),
  72. child: Column(
  73. children: <Widget>[
  74. Padding(
  75. padding: const EdgeInsets.fromLTRB(ui_padding, 14.0, ui_padding, 14.0),
  76. child: Row(
  77. crossAxisAlignment: CrossAxisAlignment.start,
  78. children: <Widget>[
  79. GestureDetector(
  80. onTap: () => NavigatorUtil.goPage(context, (context) => GameDetailsPage(item.game)),
  81. child: ClipRRect(
  82. child: CachedNetworkImage(
  83. width: 50,
  84. height: 50,
  85. imageUrl: item.game?.cover,
  86. fit: BoxFit.cover,
  87. ),
  88. // 也可控件一边圆角大小
  89. borderRadius: new BorderRadius.all(Radius.circular(6.0)),
  90. ),
  91. ),
  92. SizedBox(
  93. width: ui_padding,
  94. ),
  95. Expanded(
  96. child: Column(
  97. children: <Widget>[
  98. Text("${item.game?.name}", style: Theme.of(context).textTheme.headline1.copyWith(fontSize: 16.0)),
  99. const SizedBox(
  100. height: 6.0,
  101. ),
  102. Text(
  103. "最近打开:${item.lastPlayAt}",
  104. style: Theme.of(context).textTheme.bodyText1,
  105. ),
  106. ],
  107. crossAxisAlignment: CrossAxisAlignment.start,
  108. )),
  109. RichText(
  110. text: TextSpan(style: DefaultTextStyle.of(context).style, children: <InlineSpan>[
  111. TextSpan(text: '详情\t', style: Theme.of(context).textTheme.subtitle2),
  112. WidgetSpan(
  113. alignment: PlaceholderAlignment.middle,
  114. child: arrowRight(),
  115. ),
  116. ]),
  117. ),
  118. ],
  119. ),
  120. ),
  121. Divider(
  122. height: 0.5,
  123. ),
  124. Padding(
  125. padding: const EdgeInsets.fromLTRB(ui_padding, 15.0, ui_padding, 15.0),
  126. child: Row(
  127. children: <Widget>[
  128. Column(
  129. children: <Widget>[
  130. Text("${item.durationTotalMinute}", style: Theme.of(context).textTheme.headline1.copyWith(fontSize: 20.0)),
  131. const SizedBox(
  132. height: 2.0,
  133. ),
  134. Text(
  135. "总时长(分钟)",
  136. style: Theme.of(context).textTheme.bodyText1,
  137. ),
  138. ],
  139. ),
  140. Column(
  141. children: <Widget>[
  142. Text("${item.scoreMax.toStringAsFixed(1)}",
  143. style: Theme.of(context).textTheme.headline1.copyWith(fontSize: 20.0)),
  144. const SizedBox(
  145. height: 2.0,
  146. ),
  147. Text(
  148. "最高评分",
  149. style: Theme.of(context).textTheme.bodyText1,
  150. ),
  151. ],
  152. ),
  153. Column(
  154. children: <Widget>[
  155. Text("${item.times}", style: Theme.of(context).textTheme.headline1.copyWith(fontSize: 20.0)),
  156. const SizedBox(
  157. height: 2.0,
  158. ),
  159. Text(
  160. "运动次数(次)",
  161. style: Theme.of(context).textTheme.bodyText1,
  162. ),
  163. ],
  164. ),
  165. ],
  166. mainAxisAlignment: MainAxisAlignment.spaceAround,
  167. ),
  168. ),
  169. ],
  170. )),
  171. );
  172. },
  173. childCount: model.list.length,
  174. ),
  175. ),
  176. ),
  177. if (model.isEmpty)
  178. SliverToBoxAdapter(
  179. child: Container(
  180. margin: const EdgeInsets.fromLTRB(ui_padding, 14.0, ui_padding, 14.0),
  181. decoration: circular(),
  182. child: RequestErrorWidget(
  183. null,
  184. assets: RequestErrorWidget.ASSETS_NO_MOTION,
  185. msg: "您还未进行任何运动",
  186. ))),
  187. ],
  188. ));
  189. }),
  190. );
  191. }
  192. @override
  193. SimpleModel createModel() => SimpleModel((page) async {
  194. return (await api.getGameRecordSum()).results;
  195. });
  196. }