achievement_page.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. import 'dart:math';
  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_staggered_grid_view/flutter_staggered_grid_view.dart';
  6. import 'package:sport/bean/achievement_info.dart';
  7. import 'package:sport/bean/user.dart';
  8. import 'package:sport/provider/achievement_info_model.dart';
  9. import 'package:sport/router/navigator_util.dart';
  10. import 'package:sport/widgets/appbar.dart';
  11. import 'package:sport/widgets/box.dart';
  12. import 'package:sport/widgets/error.dart';
  13. import 'package:sport/widgets/misc.dart';
  14. import 'package:sport/widgets/space.dart';
  15. class AchievementPage extends StatefulWidget {
  16. final AchievementInfoData data;
  17. AchievementPage(this.data);
  18. @override
  19. State<StatefulWidget> createState() => _PageState();
  20. }
  21. class _PageState extends State<AchievementPage> {
  22. AchievementInfoModel _achievementInfoModel = new AchievementInfoModel(1);
  23. @override
  24. void initState() {
  25. // TODO: implement initState
  26. super.initState();
  27. initData();
  28. }
  29. initData() async {
  30. await _achievementInfoModel.getAchievementInfo();
  31. }
  32. @override
  33. Widget build(BuildContext context) {
  34. return Scaffold(
  35. // provider 只能有一个?
  36. body: CustomScrollView(slivers: <Widget>[
  37. buildSliverAppBar(context, "我的成就", backgroundColor: Theme.of(context).scaffoldBackgroundColor),
  38. SliverToBoxAdapter(
  39. child: Padding(
  40. padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 13.0),
  41. child: Column(
  42. children: <Widget>[
  43. Row(children: <Widget>[
  44. Text("我的勋章: ", style: Theme.of(context).textTheme.bodyText2.copyWith(color: Color(0xff666666))),
  45. Text("${widget.data.getAchievementCount}枚勋章已获得", style: Theme.of(context).textTheme.bodyText2.copyWith(color: Theme.of(context).accentColor))
  46. ]),
  47. Padding(
  48. padding: EdgeInsets.symmetric(vertical: 10.0),
  49. child: ClipRRect(
  50. borderRadius: BorderRadius.circular(10),
  51. child: Container(
  52. child: CustomPaint(
  53. painter: _ProgressBar(
  54. // 1.0
  55. widget.data.exp / (widget.data.nextLevelExp + widget.data.exp), Color(0xffdcdcdc)
  56. ),
  57. child: Container(
  58. height: 12,
  59. ),
  60. ),
  61. ),
  62. ),
  63. ),
  64. Container(
  65. alignment: Alignment.centerLeft,
  66. child: Text("收集进度 ${widget.data.getAchievementPercent}%", style: Theme.of(context).textTheme.bodyText1.copyWith(fontSize: 11.0)),
  67. ),
  68. ],
  69. ),
  70. )),
  71. SliverToBoxAdapter(
  72. child: BoxWidget(
  73. body: Column(
  74. children: <Widget>[
  75. Padding(
  76. padding: const EdgeInsets.symmetric(vertical: 8.0),
  77. child: Row(
  78. children: <Widget>[
  79. Expanded(
  80. child: Divider(
  81. endIndent: 10.0,
  82. ),
  83. ),
  84. Text("已获得成就"
  85. , style: Theme.of(context).textTheme.bodyText1,),
  86. Expanded(
  87. child: Divider(
  88. indent: 10.0,
  89. )),
  90. ],
  91. ),
  92. ),
  93. if (widget.data.getAchievementList.length == 0)
  94. Padding(
  95. padding: const EdgeInsets.all(24.0),
  96. child: Column(
  97. children: <Widget>[
  98. Image.asset("lib/assets/img/${RequestErrorWidget.ASSETS_NO_RANK}"),
  99. Padding(
  100. padding: const EdgeInsets.fromLTRB(0, 12, 0, 12),
  101. child: Text("还未获得任何成就",style: Theme.of(context).textTheme.bodyText2,),
  102. ),
  103. ],
  104. )),
  105. if (widget.data.getAchievementList.length > 0)
  106. Padding(
  107. padding: EdgeInsets.symmetric(vertical: 16.0),
  108. child: StaggeredGridView.countBuilder(
  109. padding: EdgeInsets.zero,
  110. shrinkWrap: true,
  111. physics: NeverScrollableScrollPhysics(),
  112. crossAxisCount: 3,
  113. itemCount: widget.data.getAchievementList.length,
  114. itemBuilder: (BuildContext context, int index) => achievementWidget(context, widget.data.getAchievementList[index], isRadius: false,w: 84),
  115. mainAxisSpacing: 18.0,
  116. crossAxisSpacing: 12.0,
  117. staggeredTileBuilder: (int index) => StaggeredTile.fit(1),
  118. ),
  119. ),
  120. if (widget.data.getAchievementList.length > 0)
  121. Center(
  122. child: Row(
  123. mainAxisSize: MainAxisSize.min,
  124. children: <Widget>[
  125. Image.asset("lib/assets/img/icon_problem.png"),
  126. SizedBox(width: 2,),
  127. Text(
  128. "默认排序按最近获得顺序",
  129. style: Theme.of(context).textTheme.bodyText1.copyWith(color: Color(0xffcecece)),
  130. ),
  131. ],
  132. ),
  133. ),
  134. Padding(
  135. padding: EdgeInsets.only(top: 31.0),
  136. child: Row(
  137. children: <Widget>[
  138. Expanded(
  139. child: Divider(
  140. endIndent: 10.0,
  141. ),
  142. ),
  143. Text("未获得成就", style: Theme.of(context).textTheme.bodyText1),
  144. Expanded(
  145. child: Divider(
  146. indent: 10.0,
  147. )),
  148. ],
  149. ),
  150. ),
  151. getList(widget.data)
  152. ],
  153. ),
  154. ),
  155. ),
  156. ]),
  157. );
  158. }
  159. }
  160. ListView getList(data) {
  161. return ListView.builder(
  162. padding: EdgeInsets.zero,
  163. physics: NeverScrollableScrollPhysics(),
  164. itemCount: data?.remainAchievementList?.length ?? 0,
  165. shrinkWrap: true,
  166. itemBuilder: (BuildContext context, int index) {
  167. Achievement item = data.remainAchievementList[index];
  168. return Padding(
  169. padding: EdgeInsets.symmetric(vertical: 15.0),
  170. child: Column(
  171. children: <Widget>[
  172. Row(
  173. crossAxisAlignment: CrossAxisAlignment.start,
  174. children: <Widget>[
  175. Column(
  176. children: <Widget>[
  177. ColorFiltered(
  178. colorFilter: ColorFilter.mode(Colors.white, BlendMode.color),
  179. child: CachedNetworkImage(width: 70.0, height: 70.0, imageUrl: item.logo),
  180. ),
  181. ],
  182. ),
  183. Space(
  184. width: 12,
  185. ),
  186. Expanded(
  187. child: Column(
  188. crossAxisAlignment: CrossAxisAlignment.start,
  189. children: <Widget>[
  190. Row(
  191. children: <Widget>[
  192. Text("成就名称:", style: Theme.of(context).textTheme.subtitle1),
  193. Text("${item.name}", style: Theme.of(context).textTheme.bodyText2.copyWith(color: Theme.of(context).accentColor))
  194. ],
  195. ),
  196. Space(
  197. height: 5,
  198. ),
  199. Row(
  200. children: <Widget>[
  201. Text("成就奖励:", style: Theme.of(context).textTheme.subtitle1),
  202. Text("经验值+${item.rewardExp},积分+${item.rewardScore}", style: Theme.of(context).textTheme.bodyText2)
  203. ],
  204. ),
  205. Space(
  206. height: 5,
  207. ),
  208. Row(
  209. children: <Widget>[
  210. Text("成就条件:", style: Theme.of(context).textTheme.subtitle1),
  211. Expanded(
  212. child: Text("${item.conditionDetail}", style: Theme.of(context).textTheme.bodyText2),
  213. ),
  214. ],
  215. crossAxisAlignment: CrossAxisAlignment.start,
  216. ),
  217. ],
  218. ),
  219. ),
  220. ],
  221. ),
  222. Space(
  223. height: 8,
  224. ),
  225. Row(
  226. mainAxisAlignment: MainAxisAlignment.end,
  227. children: <Widget>[
  228. Text(
  229. '${item.conditionProgress}',
  230. style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor,fontSize: 12),
  231. ),
  232. Text(
  233. '/${item.conditionCount}',
  234. style: Theme.of(context).textTheme.bodyText1,
  235. )
  236. ],
  237. ),
  238. Space(
  239. height: 2,
  240. ),
  241. ClipRRect(
  242. borderRadius: BorderRadius.circular(12),
  243. child: Container(
  244. child: CustomPaint(
  245. painter: _ProgressBar(item.conditionProgress / (item.conditionCount + item.conditionProgress), Color(0xfff1f1f1)),
  246. child: Container(
  247. height: 8,
  248. ),
  249. ),
  250. ),
  251. ),
  252. ],
  253. ),
  254. );
  255. },
  256. );
  257. }
  258. class _ProgressBar extends CustomPainter {
  259. final Color bg;
  260. Paint _paint;
  261. final Paint _indicatorPaint = Paint()
  262. ..color = Color(0xffFFC400)
  263. ..isAntiAlias = true;
  264. double _paddingBar = 2;
  265. double percent;
  266. _ProgressBar(this.percent,this.bg){
  267. _paint = Paint()
  268. ..color = bg
  269. ..isAntiAlias = true;
  270. }
  271. @override
  272. void paint(Canvas canvas, Size size) {
  273. double indicator = size.width * min(1.0, this.percent);
  274. canvas.save();
  275. var rect = Rect.fromLTRB(0, size.height - 13, size.width, size.height);
  276. canvas.clipRRect(RRect.fromRectAndRadius(rect, Radius.circular(size.height / 2)), doAntiAlias: true);
  277. canvas.drawRect(rect, _paint);
  278. Paint _valuePaint = Paint()
  279. ..shader = LinearGradient(
  280. begin: Alignment.centerLeft,
  281. end: Alignment.centerRight,
  282. colors: <Color>[Color(0xffFFE600), Color(0xffFF9100)],
  283. ).createShader(rect);
  284. canvas.drawRect(Rect.fromLTRB(0, size.height - 13, size.width * this.percent, size.height), _valuePaint);
  285. canvas.restore();
  286. Path path = Path()
  287. ..moveTo(indicator, size.height - 13 - _paddingBar)
  288. ..lineTo(indicator - 5, 0)
  289. ..lineTo(indicator + 5, 0)
  290. ..close();
  291. canvas.drawPath(path, _indicatorPaint);
  292. }
  293. @override
  294. bool shouldRepaint(CustomPainter oldDelegate) {
  295. return false;
  296. }
  297. }