achievement_detail_page.dart 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. import 'dart:math';
  2. import 'dart:ui';
  3. import 'package:cached_network_image/cached_network_image.dart';
  4. import 'package:flutter/cupertino.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter_easyrefresh/easy_refresh.dart';
  7. import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
  8. import 'package:flutter_swiper/flutter_swiper.dart';
  9. import 'package:sport/bean/achievement_detail_info.dart';
  10. import 'package:sport/bean/user.dart';
  11. import 'package:sport/provider/lib/provider_widget.dart';
  12. import 'package:sport/provider/lib/simple_model.dart';
  13. import 'package:sport/services/api/inject_api.dart';
  14. import 'package:sport/widgets/appbar.dart';
  15. import 'package:sport/widgets/box.dart';
  16. import 'package:sport/widgets/loading.dart';
  17. import 'package:sport/widgets/misc.dart';
  18. import 'package:sport/widgets/space.dart';
  19. class AchievementDetailPage extends StatefulWidget {
  20. final int id;
  21. final int userId;
  22. AchievementDetailPage(this.id, this.userId);
  23. @override
  24. State<StatefulWidget> createState() {
  25. return _PageState();
  26. }
  27. }
  28. class _PageState extends State<AchievementDetailPage> with InjectLoginApi {
  29. SimpleModel _model;
  30. @override
  31. void initState() {
  32. super.initState();
  33. // _model = SimpleModel((page) async {
  34. // return List()..add((await loginApi.getAchieveDetailInfo(widget.id, userId: widget.userId == 0 ? null : "${widget.userId}")).data);
  35. // });
  36. }
  37. // @override
  38. // Widget build(BuildContext context) {
  39. // return Scaffold(
  40. //// backgroundColor: Color(0xffF1F1F1),
  41. // body: ProviderWidget<SimpleModel>(
  42. // model: _model,
  43. // onModelReady: (model) => model.initData(),
  44. // builder: (_, model, __) {
  45. // AchieveDetailInfoData _data = _model.list?.isNotEmpty == true ? _model.list.first : AchieveDetailInfoData();
  46. // return EasyRefresh.custom(
  47. // controller: model.refreshController,
  48. // enableControlFinishRefresh: true,
  49. // enableControlFinishLoad: true,
  50. // // onRefresh: () => model.refresh(),
  51. //// header: buildClassicalHeader(),
  52. //// footer: buildClassicalFooter(),
  53. // slivers: <Widget>[
  54. // buildSliverAppBar(context, "成就详情", backgroundColor: Theme.of(context).scaffoldBackgroundColor),
  55. // if (model.isBusy)
  56. // SliverToBoxAdapter(
  57. // child: RequestLoadingWidget(),
  58. // ),
  59. // if (model.isIdle)
  60. // SliverToBoxAdapter(
  61. // child: BoxWidget(
  62. // body: Column(
  63. // crossAxisAlignment: CrossAxisAlignment.center,
  64. // children: <Widget>[
  65. // Space(height: 10.0),
  66. // CachedNetworkImage(
  67. // width: 130.0,
  68. // height: 130.0,
  69. // imageUrl: _data.logo ?? "",
  70. // ),
  71. // Space(height: 12.0),
  72. // Text("${_data.name}", style: Theme.of(context).textTheme.headline3),
  73. // Space(height: 17.0),
  74. // Divider(),
  75. // Space(height: 12.0),
  76. // Row(
  77. // mainAxisAlignment: MainAxisAlignment.spaceBetween,
  78. // children: <Widget>[
  79. // Text("成就名称:", style: Theme.of(context).textTheme.subtitle1),
  80. // Text("${_data.name}", style: Theme.of(context).textTheme.bodyText2.copyWith(color: Theme.of(context).accentColor))
  81. // ],
  82. // ),
  83. // Space(height: 8.0),
  84. // Row(
  85. // mainAxisAlignment: MainAxisAlignment.spaceBetween,
  86. // children: <Widget>[
  87. // Text("成就条件:", style: Theme.of(context).textTheme.subtitle1),
  88. // Text("${_data.conditionDetail}", style: Theme.of(context).textTheme.bodyText2)
  89. // ],
  90. // ),
  91. // Space(height: 8.0),
  92. // Row(
  93. // mainAxisAlignment: MainAxisAlignment.spaceBetween,
  94. // children: <Widget>[
  95. // Text("获取时间:", style: Theme.of(context).textTheme.subtitle1),
  96. // Text("${_data.createdAt ?? '未获得成就'}", style: Theme.of(context).textTheme.bodyText2)
  97. // ],
  98. // ),
  99. // Space(height: 8.0),
  100. // ],
  101. // ),
  102. // ),
  103. // ),
  104. // if (model.isIdle)
  105. // SliverToBoxAdapter(
  106. // child: BoxWidget(
  107. // body: Column(
  108. // crossAxisAlignment: CrossAxisAlignment.start,
  109. // children: <Widget>[
  110. // Row(
  111. // mainAxisAlignment: MainAxisAlignment.spaceBetween,
  112. // children: <Widget>[
  113. // Text("晋级奖励:", style: Theme.of(context).textTheme.subtitle1),
  114. // Text("经验值 +${_data.rewardExp} 积分+${_data.rewardScore}",
  115. // style: Theme.of(context).textTheme.bodyText2.copyWith(color: Theme.of(context).accentColor))
  116. // ],
  117. // ),
  118. // Space(height: 4.0),
  119. // Divider(),
  120. // Space(height: 4.0),
  121. // Text("晋级进度: ", style: Theme.of(context).textTheme.subtitle1),
  122. // Padding(
  123. // padding: EdgeInsets.symmetric(vertical: 10.0),
  124. // child: ClipRRect(
  125. // borderRadius: BorderRadius.circular(12),
  126. // child: Container(
  127. // child: CustomPaint(
  128. // painter: _ProgressBar(
  129. // ((_data?.nextConditionCount ?? 0) > 0) ? _data.conditionProgress / _data.nextConditionCount : 0,
  130. // ),
  131. // child: Container(
  132. // height: 8,
  133. // ),
  134. // ),
  135. // ),
  136. // ),
  137. // ),
  138. // Row(
  139. // mainAxisAlignment: MainAxisAlignment.spaceBetween,
  140. // children: <Widget>[
  141. // Text('${_data.conditionProgress}${_data.conditionMeasure}', style: Theme.of(context).textTheme.bodyText1.copyWith(fontSize: 11.0)),
  142. // Text('${_data.nextConditionCount}${_data.conditionMeasure}', style: Theme.of(context).textTheme.bodyText1.copyWith(fontSize: 11.0))
  143. // ],
  144. // )
  145. // ],
  146. // ),
  147. // ),
  148. // ),
  149. // if (model.isIdle)
  150. // SliverToBoxAdapter(
  151. // child: Padding(
  152. // padding: const EdgeInsets.all(12.0),
  153. // child: Column(
  154. // children: <Widget>[
  155. // Row(
  156. // children: <Widget>[
  157. // Expanded(
  158. // child: Divider(
  159. // endIndent: 10.0,
  160. // ),
  161. // ),
  162. // Text("成就组"),
  163. // Expanded(
  164. // child: Divider(
  165. // indent: 10.0,
  166. // )),
  167. // ],
  168. // ),
  169. // ],
  170. // ),
  171. // )),
  172. // if (_data.relateAchievements?.length == 0)
  173. // Padding(padding: const EdgeInsets.all(24.0), child: Text("没有关联成就", style: Theme.of(context).textTheme.bodyText1)),
  174. // if (model.isIdle && _data.relateAchievements.isNotEmpty)
  175. // SliverToBoxAdapter(
  176. // child: Text("${_data.relateAchievements}"),
  177. // ),
  178. //// SliverToBoxAdapter(
  179. //// child: StaggeredGridView.countBuilder(
  180. //// padding: EdgeInsets.symmetric(horizontal: 12.0),
  181. //// shrinkWrap: true,
  182. //// physics: NeverScrollableScrollPhysics(),
  183. //// crossAxisCount: 4,
  184. //// itemCount: _data.relateAchievements?.length,
  185. //// itemBuilder: (BuildContext context, int index) =>
  186. //// achievementWidget(context, _data.relateAchievements[index], replace: true, isRadius: false, jump: false),
  187. //// mainAxisSpacing: 12.0,
  188. //// crossAxisSpacing: 12.0,
  189. //// staggeredTileBuilder: (int index) => StaggeredTile.fit(1),
  190. //// ),
  191. //// )
  192. // ],
  193. // );
  194. // },
  195. // ));
  196. // }
  197. @override
  198. Widget build(BuildContext context) {
  199. // TODO: implement build
  200. // throw UnimplementedError();
  201. return Material(color: Colors.black.withOpacity(0.5), child: Column());
  202. }
  203. }
  204. class _ProgressBar extends CustomPainter {
  205. final Paint _paint = Paint()
  206. ..color = Color(0xfff1f1f1)
  207. ..isAntiAlias = true;
  208. final Paint _indicatorPaint = Paint()
  209. ..color = Color(0xffFFC400)
  210. ..isAntiAlias = true;
  211. double _paddingBar = 2;
  212. double percent;
  213. _ProgressBar(this.percent);
  214. @override
  215. void paint(Canvas canvas, Size size) {
  216. double indicator = size.width * min(1.0, this.percent);
  217. canvas.save();
  218. var rect = Rect.fromLTRB(0, size.height - 13, size.width, size.height);
  219. canvas.clipRRect(
  220. RRect.fromRectAndRadius(rect, Radius.circular(size.height / 2)),
  221. doAntiAlias: true);
  222. canvas.drawRect(rect, _paint);
  223. Paint _valuePaint = Paint()
  224. ..shader = LinearGradient(
  225. begin: Alignment.centerLeft,
  226. end: Alignment.centerRight,
  227. colors: <Color>[Color(0xffFFE600), Color(0xffFF9100)],
  228. ).createShader(rect);
  229. canvas.drawRect(
  230. Rect.fromLTRB(
  231. 0, size.height - 13, size.width * this.percent, size.height),
  232. _valuePaint);
  233. canvas.restore();
  234. Path path = Path()
  235. ..moveTo(indicator, size.height - 13 - _paddingBar)
  236. ..lineTo(indicator - 5, 0)
  237. ..lineTo(indicator + 5, 0)
  238. ..close();
  239. canvas.drawPath(path, _indicatorPaint);
  240. }
  241. @override
  242. bool shouldRepaint(CustomPainter oldDelegate) {
  243. return false;
  244. }
  245. }
  246. Future<bool> showSharePopup(
  247. BuildContext context, List<Achievement> relateAchievements, int id) {
  248. Iterable<Achievement> item =
  249. relateAchievements.where((element) => element.id == id);
  250. int startIndex = relateAchievements.indexOf(item.toList()[0]);
  251. ValueNotifier<int> _valueNotifierIndex = ValueNotifier(startIndex);
  252. int currentIndex = startIndex;
  253. return showGeneralDialog<bool>(
  254. context: context,
  255. barrierDismissible: true,
  256. barrierLabel: '',
  257. // barrierColor: Color(0xff241D19).withOpacity(0.8),
  258. transitionDuration: Duration(milliseconds: 200),
  259. // useRootNavigator: false,
  260. pageBuilder: (BuildContext context, Animation<double> animation,
  261. Animation<double> secondaryAnimation) {
  262. return BackdropFilter(
  263. filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
  264. child: Material(
  265. color: Colors.transparent.withOpacity(0.8),
  266. child: Column(
  267. // mainAxisSize: MainAxisSize.max,
  268. children: <Widget>[
  269. Space(
  270. height: MediaQuery.of(context).padding.top + 31,
  271. ),
  272. Column(
  273. mainAxisSize: MainAxisSize.max,
  274. mainAxisAlignment: MainAxisAlignment.start,
  275. children: <Widget>[
  276. Container(
  277. padding: EdgeInsets.symmetric(horizontal: 17.0),
  278. alignment: Alignment.centerRight,
  279. child: InkWell(
  280. child: Container(
  281. width: 22.0,
  282. height: 22.0,
  283. decoration: BoxDecoration(
  284. image: DecorationImage(
  285. image: AssetImage(
  286. "lib/assets/img/btn_close_white.png"))),
  287. ),
  288. onTap: () {
  289. Navigator.pop(context, false);
  290. },
  291. )),
  292. Space(
  293. height: 115,
  294. ),
  295. Stack(
  296. // fit: StackFit.expand,
  297. alignment: Alignment.topCenter,
  298. overflow: Overflow.visible,
  299. children: <Widget>[
  300. Container(
  301. height: 278,
  302. child: new Swiper(
  303. // itemWidth: MediaQuery.of(context).size.width,
  304. loop: false,
  305. index: startIndex,
  306. itemBuilder: (BuildContext context, int index) {
  307. return Column(
  308. children: <Widget>[
  309. relateAchievements[index].createdAt != ""
  310. ? index != currentIndex
  311. ? Opacity(
  312. opacity: 0.5,
  313. child: Container(
  314. child: CachedNetworkImage(
  315. imageUrl:
  316. relateAchievements[index]
  317. .logo,
  318. width: 180,
  319. height: 180,
  320. )))
  321. : Container(
  322. child: CachedNetworkImage(
  323. imageUrl:
  324. relateAchievements[index]
  325. .logo,
  326. width: 180,
  327. height: 180,
  328. ))
  329. : index == currentIndex
  330. ? ColorFiltered(
  331. colorFilter:
  332. ColorFilter.matrix(<double>[
  333. 0.2126,
  334. 0.7152,
  335. 0.0722,
  336. 0,
  337. 0,
  338. 0.2126,
  339. 0.7152,
  340. 0.0722,
  341. 0,
  342. 0,
  343. 0.2126,
  344. 0.7152,
  345. 0.0722,
  346. 0,
  347. 0,
  348. 0,
  349. 0,
  350. 0,
  351. 1,
  352. 0,
  353. ]),
  354. child: CachedNetworkImage(
  355. // width: 70.0,
  356. // height: 70.0,
  357. imageUrl:
  358. relateAchievements[index]
  359. .logo),
  360. )
  361. : Opacity(
  362. opacity: 0.5,
  363. child: ColorFiltered(
  364. colorFilter:
  365. ColorFilter.matrix(<double>[
  366. 0.2126,
  367. 0.7152,
  368. 0.0722,
  369. 0,
  370. 0,
  371. 0.2126,
  372. 0.7152,
  373. 0.0722,
  374. 0,
  375. 0,
  376. 0.2126,
  377. 0.7152,
  378. 0.0722,
  379. 0,
  380. 0,
  381. 0,
  382. 0,
  383. 0,
  384. 1,
  385. 0,
  386. ]),
  387. child: CachedNetworkImage(
  388. // width: 70.0,
  389. // height: 70.0,
  390. imageUrl:
  391. relateAchievements[
  392. index]
  393. .logo),
  394. ),
  395. ),
  396. // if (index == currentIndex)
  397. // Column(
  398. // children: <Widget>[
  399. // Space(
  400. // height: 20.0,
  401. // ),
  402. // Space(
  403. // height: 5.0,
  404. // ),
  405. // ],
  406. // )
  407. ],
  408. );
  409. },
  410. viewportFraction: 0.5,
  411. scale: 0.3,
  412. itemCount: relateAchievements.length,
  413. pagination: new SwiperPagination(
  414. margin: new EdgeInsets.symmetric(vertical: 0.0),
  415. builder: DotSwiperPaginationBuilder(
  416. size: 6,
  417. activeSize: 6,
  418. color: Colors.white.withOpacity(0.5),
  419. activeColor:
  420. Theme.of(context).accentColor)),
  421. onIndexChanged: (index) {
  422. _valueNotifierIndex.value = index;
  423. currentIndex = index;
  424. },
  425. ),
  426. ),
  427. Positioned(
  428. // top: 120.0,
  429. top: 175,
  430. child: Container(
  431. child: ValueListenableBuilder(
  432. valueListenable: _valueNotifierIndex,
  433. builder: (BuildContext context, int value,
  434. Widget child) {
  435. if (currentIndex == value) {
  436. return relateAchievements[value]
  437. .createdAt !=
  438. ""
  439. ? Column(
  440. mainAxisSize: MainAxisSize.min,
  441. children: <Widget>[
  442. Space(
  443. height: 25.0,
  444. ),
  445. Text(
  446. "${relateAchievements[value].name}",
  447. style: TextStyle(
  448. fontSize: 18.0,
  449. color: Colors.white,
  450. fontWeight:
  451. FontWeight.w600),
  452. ),
  453. Space(
  454. height: 10.0,
  455. ),
  456. Container(
  457. alignment: Alignment.center,
  458. child: Text(
  459. "${relateAchievements[value].conditionDetail}",
  460. style: TextStyle(
  461. fontSize: 14.0,
  462. color: Colors.white)),
  463. ),
  464. Space(
  465. height: 60.0,
  466. ),
  467. Text(
  468. "获取时间 ${relateAchievements[value].createdAt.split(" ")[0]}"),
  469. Space(
  470. height: 16.0,
  471. ),
  472. Container(
  473. alignment: Alignment.center,
  474. height: 37.5,
  475. width: MediaQuery.of(context)
  476. .size
  477. .width,
  478. decoration: BoxDecoration(
  479. image: DecorationImage(
  480. image: AssetImage(
  481. "lib/assets/img/bg1_pop_achievement.png"),
  482. fit: BoxFit.cover)),
  483. child: Text(
  484. "晋级奖励 : 经验值 +${relateAchievements[value].rewardExp} 积分 +${relateAchievements[value].rewardScore}",
  485. style: TextStyle(
  486. fontSize: 14.0,
  487. color: Theme.of(context)
  488. .accentColor,
  489. ),
  490. strutStyle: fixedLine,
  491. ),
  492. ),
  493. ],
  494. )
  495. : Column(
  496. children: <Widget>[
  497. Space(
  498. height: 25.0,
  499. ),
  500. Text(
  501. "${relateAchievements[value].name}",
  502. style: TextStyle(
  503. fontSize: 18.0,
  504. color: Colors.white,
  505. fontWeight:
  506. FontWeight.w600
  507. ),
  508. ),
  509. Space(
  510. height: 10.0,
  511. ),
  512. Text(
  513. "成就条件: ${relateAchievements[value].conditionDetail}",
  514. style: TextStyle(
  515. fontSize: 14.0,
  516. color: Colors.white),
  517. ),
  518. Space(
  519. height: 60.0,
  520. ),
  521. Text("未获得"),
  522. Space(
  523. height: 12.0,
  524. ),
  525. Text(
  526. "晋级奖励 : 经验值 +${relateAchievements[value].rewardExp} 积分 +${relateAchievements[value].rewardScore}",
  527. style: TextStyle(
  528. fontSize: 14.0,
  529. color: Color(0xff999999)),
  530. ),
  531. // Space(
  532. // height: 8.0,
  533. // ),
  534. Padding(
  535. padding: EdgeInsets.symmetric(
  536. vertical: 10.0),
  537. child: ClipRRect(
  538. borderRadius:
  539. BorderRadius.circular(12),
  540. child: Container(
  541. width: 183.0,
  542. child: CustomPaint(
  543. painter: _ProgressBar(
  544. ((relateAchievements[
  545. value]
  546. ?.conditionProgress ??
  547. 0) >
  548. 0)
  549. ? relateAchievements[
  550. value]
  551. .conditionProgress /
  552. relateAchievements[
  553. value]
  554. .conditionCount
  555. : 0,
  556. ),
  557. child: Container(
  558. height: 8,
  559. ),
  560. ),
  561. ),
  562. ),
  563. ),
  564. // Space(
  565. // height: 5.0,
  566. // ),
  567. Text(
  568. "${relateAchievements[value].conditionProgress} / ${relateAchievements[value].conditionCount}")
  569. ],
  570. );
  571. } else {
  572. return Container();
  573. }
  574. }),
  575. ),
  576. ),
  577. ],
  578. )
  579. ],
  580. ),
  581. ],
  582. ),
  583. ),
  584. );
  585. });
  586. }