achievement_page.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  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/widgets/appbar.dart';
  10. import 'package:sport/widgets/box.dart';
  11. import 'package:sport/widgets/error.dart';
  12. import 'package:sport/widgets/misc.dart';
  13. import 'package:sport/widgets/space.dart';
  14. class AchievementPage extends StatefulWidget {
  15. final AchievementInfoData data;
  16. AchievementPage(this.data);
  17. @override
  18. State<StatefulWidget> createState() => _PageState();
  19. }
  20. class _PageState extends State<AchievementPage> {
  21. AchievementInfoModel _achievementInfoModel = new AchievementInfoModel(1);
  22. late ScrollController _controller;
  23. double _expandedHeight = 0;
  24. int _brightness = 0;
  25. @override
  26. void initState() {
  27. super.initState();
  28. initData();
  29. _controller = ScrollController()
  30. ..addListener(() {
  31. // print(
  32. // "[_controller.position.pixels] -------------------------- ${_controller.position.pixels}");
  33. print("[_brightness]--------------------------$_brightness");
  34. if (_controller.position.pixels >= 70) {
  35. if (_brightness == 0) {
  36. setState(() {
  37. _brightness = 1;
  38. });
  39. }
  40. } else {
  41. if (_brightness == 1) {
  42. setState(() {
  43. _brightness = 0;
  44. });
  45. }
  46. }
  47. });
  48. }
  49. initData() async {
  50. await _achievementInfoModel.getAchievementInfo();
  51. }
  52. initScrollController() {}
  53. @override
  54. Widget build(BuildContext context) {
  55. return Scaffold(
  56. body: Stack(
  57. alignment: Alignment.topCenter,
  58. children: <Widget>[
  59. Container(
  60. color: Color(0xff241D19),
  61. height: double.infinity,
  62. ),
  63. Positioned(
  64. top: 10,
  65. left: 0,
  66. right: 0,
  67. child: Image.asset(
  68. 'lib/assets/img/myachievements_bg.png',
  69. fit: BoxFit.fitWidth,
  70. ),
  71. ),
  72. CustomScrollView(controller: _controller, slivers: <Widget>[
  73. buildSliverAppBar(
  74. context,
  75. "我的成就",
  76. backgroundColor: _brightness == 0 ? Color(0x00000000) : Color(0xffffffff),
  77. brightness: _brightness == 0 ? 1 : 0,
  78. textStyle: _brightness == 0
  79. ? TextStyle(fontWeight: FontWeight.w600, fontSize: 18.0, color: Color(0xffffffff))
  80. : TextStyle(fontWeight: FontWeight.w600, fontSize: 18.0, color: Color(0xff333333)),
  81. whiteBackButton: _brightness == 0 ? true : false,
  82. canBack: _brightness == 0 ? false : true,
  83. ),
  84. SliverToBoxAdapter(
  85. child: Padding(
  86. padding: EdgeInsets.symmetric(vertical: 0.0, horizontal: 13.0),
  87. child: Column(
  88. children: <Widget>[
  89. Row(crossAxisAlignment: CrossAxisAlignment.end, children: <Widget>[
  90. RichText(
  91. text: TextSpan(
  92. text: '累计获得',
  93. style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Color(0xffffffff)),
  94. children: <TextSpan>[
  95. TextSpan(
  96. text: "${widget.data.getAchievementCount}",
  97. style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Theme.of(context).accentColor, fontSize: 28.0)),
  98. TextSpan(text: '枚勋章', style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Color(0xffffffff)))
  99. ],
  100. ),
  101. )
  102. ]),
  103. Padding(
  104. padding: EdgeInsets.symmetric(vertical: 10.0),
  105. child: ClipRRect(
  106. borderRadius: BorderRadius.circular(10),
  107. child: Container(
  108. alignment: Alignment.centerLeft,
  109. child: CustomPaint(
  110. painter: _ProgressBar(
  111. // 1.0
  112. // widget.data.exp / (widget.data.nextLevelExp + widget.data.exp),
  113. (widget.data.getAchievementPercent??0.0) / 100.0,
  114. Color(0xffdcdcdc)),
  115. child: Container(
  116. height: 12,
  117. width: 140,
  118. ),
  119. ),
  120. ),
  121. ),
  122. ),
  123. Container(
  124. alignment: Alignment.centerLeft,
  125. child: Text("收集进度 ${widget.data.getAchievementPercent}%",
  126. style: Theme.of(context).textTheme.bodyText1!.copyWith(fontSize: 11.0, color: Color(0xffffffff))),
  127. ),
  128. Space(
  129. height: 16.0,
  130. )
  131. ],
  132. ),
  133. )),
  134. SliverToBoxAdapter(
  135. child: BoxWidget(
  136. paddingAll: false,
  137. body: Column(
  138. children: <Widget>[
  139. Padding(
  140. padding: const EdgeInsets.only(top: 16.0, bottom: 8.0),
  141. child:
  142. Stack(
  143. alignment: Alignment.center,
  144. children: <Widget>[
  145. Image.asset(
  146. "lib/assets/img/mine_image_achievement.png",
  147. fit: BoxFit.fitWidth,
  148. width: 240,
  149. ),
  150. Text(
  151. "已获得成就",
  152. style: Theme.of(context).textTheme.bodyText1!,
  153. ),
  154. ],
  155. )
  156. ),
  157. if ((widget.data.getAchievementList?.length ?? 0) == 0)
  158. Padding(
  159. padding: const EdgeInsets.all(24.0),
  160. child: Column(
  161. children: <Widget>[
  162. Image.asset("lib/assets/img/${RequestErrorWidget.ASSETS_NO_RANK}"),
  163. Padding(
  164. padding: const EdgeInsets.fromLTRB(0, 12, 0, 12),
  165. child: Text(
  166. "还未获得任何成就",
  167. style: Theme.of(context).textTheme.bodyText2!,
  168. ),
  169. ),
  170. ],
  171. )),
  172. if (widget.data.getAchievementList?.isNotEmpty == true)
  173. Padding(
  174. padding: EdgeInsets.fromLTRB(0.0, 16.0, 0.0, 16.0),
  175. child: AlignedGridView.count(
  176. padding: EdgeInsets.zero,
  177. shrinkWrap: true,
  178. physics: NeverScrollableScrollPhysics(),
  179. crossAxisCount: 3,
  180. itemCount: widget.data.getAchievementList!.length,
  181. itemBuilder: (BuildContext context, int index) =>
  182. achievementWidget(context, widget.data.getAchievementList![index], isRadius: false, w: 84, showCount: true),
  183. mainAxisSpacing: 20.0,
  184. crossAxisSpacing: 12.0,
  185. ),
  186. ),
  187. // if (widget.data.getAchievementList.length > 0)
  188. // Center(
  189. // child: Row(
  190. // mainAxisSize: MainAxisSize.min,
  191. // children: <Widget>[
  192. // Image.asset("lib/assets/img/icon_problem.png"),
  193. // SizedBox(
  194. // width: 2,
  195. // ),
  196. // Text(
  197. // "默认排序按最近获得顺序",
  198. // style: Theme.of(context)
  199. // .textTheme
  200. // .bodyText1
  201. // .copyWith(color: Color(0xffcecece)),
  202. // ),
  203. // ],
  204. // ),
  205. // ),
  206. ],
  207. ),
  208. ),
  209. ),
  210. SliverToBoxAdapter(
  211. child: BoxWidget(
  212. body: Column(
  213. children: <Widget>[
  214. Padding(
  215. padding: const EdgeInsets.symmetric(vertical: 8.0),
  216. child:
  217. Stack(
  218. alignment: Alignment.center,
  219. children: <Widget>[
  220. Image.asset(
  221. "lib/assets/img/mine_image_achievement.png",
  222. fit: BoxFit.fitWidth,
  223. width: 240,
  224. ),
  225. Text(
  226. "未获得成就",
  227. style: Theme.of(context).textTheme.bodyText1!,
  228. ),
  229. ],
  230. ),
  231. ),
  232. getList(widget.data)
  233. ],
  234. ),
  235. ),
  236. )
  237. ])
  238. ],
  239. ));
  240. }
  241. }
  242. ListView getList(data) {
  243. return ListView.builder(
  244. padding: EdgeInsets.zero,
  245. physics: NeverScrollableScrollPhysics(),
  246. itemCount: data?.remainAchievementList?.length ?? 0,
  247. shrinkWrap: true,
  248. itemBuilder: (BuildContext context, int index) {
  249. Achievement item = data.remainAchievementList[index];
  250. return Padding(
  251. padding: EdgeInsets.symmetric(vertical: 15.0),
  252. child: Column(
  253. children: <Widget>[
  254. Row(
  255. children: <Widget>[
  256. ColorFiltered(
  257. colorFilter: ColorFilter.mode(Colors.white, BlendMode.color),
  258. child: CachedNetworkImage(width: 70.0, height: 70.0, imageUrl: item.logo ?? ""),
  259. ),
  260. Space(
  261. width: 12,
  262. ),
  263. Expanded(
  264. child: Column(
  265. mainAxisSize: MainAxisSize.min,
  266. crossAxisAlignment: CrossAxisAlignment.start,
  267. children: <Widget>[
  268. Row(
  269. children: <Widget>[
  270. Text("成就名称:", style: Theme.of(context).textTheme.subtitle1!),
  271. Text("${item.name}", style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Theme.of(context).accentColor))
  272. ],
  273. ),
  274. Space(
  275. height: 5,
  276. ),
  277. // Row(
  278. // children: <Widget>[
  279. // Text("成就奖励:", style: Theme.of(context).textTheme.subtitle1!),
  280. // Text("经验值+${item.rewardExp},积分+${item.rewardScore}", style: Theme.of(context).textTheme.bodyText2!)
  281. // ],
  282. // ),
  283. Space(
  284. height: 5,
  285. ),
  286. Row(
  287. crossAxisAlignment: CrossAxisAlignment.start,
  288. children: <Widget>[
  289. Text("成就条件:", style: Theme.of(context).textTheme.subtitle1!),
  290. Expanded(child: Text("${item.conditionDetail}", style: Theme.of(context).textTheme.bodyText2!)),
  291. ],
  292. ),
  293. ],
  294. ),
  295. ),
  296. ],
  297. ),
  298. Space(
  299. height: 8,
  300. ),
  301. Row(
  302. mainAxisAlignment: MainAxisAlignment.end,
  303. children: <Widget>[
  304. Text(
  305. '${item.conditionProgress}',
  306. style: Theme.of(context).textTheme.subtitle1!.copyWith(color: Theme.of(context).accentColor, fontSize: 12),
  307. ),
  308. Text(
  309. '/${item.conditionCount}',
  310. style: Theme.of(context).textTheme.bodyText1!,
  311. )
  312. ],
  313. ),
  314. Space(
  315. height: 2,
  316. ),
  317. ClipRRect(
  318. borderRadius: BorderRadius.circular(12),
  319. child: Container(
  320. child: CustomPaint(
  321. painter: _ProgressBar(item.conditionProgress / (item.conditionCount), Color(0xfff1f1f1)),
  322. child: Container(
  323. height: 8,
  324. ),
  325. ),
  326. ),
  327. ),
  328. ],
  329. ),
  330. );
  331. },
  332. );
  333. }
  334. class _ProgressBar extends CustomPainter {
  335. final Color bg;
  336. late Paint _paint;
  337. final Paint _indicatorPaint = Paint()
  338. ..color = Color(0xffFFC400)
  339. ..isAntiAlias = true;
  340. double _paddingBar = 2;
  341. double percent;
  342. _ProgressBar(this.percent, this.bg) {
  343. _paint = Paint()
  344. ..color = bg
  345. ..isAntiAlias = true;
  346. }
  347. @override
  348. void paint(Canvas canvas, Size size) {
  349. double indicator = size.width * min(100.0, this.percent);
  350. var rect = Rect.fromLTRB(0, size.height - 13, size.width, size.height);
  351. canvas.drawRRect(RRect.fromRectAndRadius(rect, Radius.circular(size.height / 2)), _paint);
  352. Paint _valuePaint = Paint()
  353. ..shader = LinearGradient(
  354. begin: Alignment.centerLeft,
  355. end: Alignment.centerRight,
  356. colors: <Color>[Color(0xffFFE600), Color(0xffFF9100)],
  357. ).createShader(rect);
  358. canvas.drawRect(Rect.fromLTRB(0, size.height - 13, indicator, size.height), _valuePaint);
  359. //
  360. // Path path = Path()
  361. // ..moveTo(indicator, size.height - 13 - _paddingBar)
  362. // ..lineTo(indicator - 5, 0)
  363. // ..lineTo(indicator + 5, 0)
  364. // ..close();
  365. // canvas.drawPath(path, _indicatorPaint);
  366. }
  367. @override
  368. bool shouldRepaint(CustomPainter oldDelegate) {
  369. return false;
  370. }
  371. }