CompetitionRank.dart 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/rendering.dart';
  5. import 'package:flutter_redux/flutter_redux.dart';
  6. import 'package:wanna_battle/model/ParticipatingInfo.dart';
  7. import 'package:wanna_battle/redux/AppState.dart';
  8. import '../styles/colors.dart';
  9. import '../net/HttpManager.dart';
  10. class CompetitionRank extends StatefulWidget {
  11. final int competitionId;
  12. const CompetitionRank({Key key, this.competitionId}) : super(key: key);
  13. @override
  14. State<StatefulWidget> createState() {
  15. return CompetitionRankState();
  16. }
  17. }
  18. class CompetitionRankState extends State<CompetitionRank> {
  19. List<ParticipatingInfo> data = [];
  20. ParticipatingInfo myParticipatingInfo;
  21. Future<void> refresh() async {
  22. final res = await HttpManager.get('participatingInfo/rank', data: {'competitionId': widget.competitionId});
  23. ParticipatingInfo myParticipatingInfo;
  24. if (res.success) {
  25. List<ParticipatingInfo> list = [];
  26. for (var item in res.data) {
  27. var p = ParticipatingInfo.fromJson(item);
  28. list.add(p);
  29. if (StoreProvider.of<AppState>(context).state.userInfo.id == p.userId) {
  30. myParticipatingInfo = p;
  31. }
  32. }
  33. setState(() {
  34. data = list;
  35. this.myParticipatingInfo = myParticipatingInfo;
  36. });
  37. }
  38. }
  39. @override
  40. void initState() {
  41. super.initState();
  42. Future.delayed(Duration.zero, () {
  43. refresh();
  44. });
  45. }
  46. @override
  47. Widget build(BuildContext context) {
  48. return Scaffold(
  49. appBar: AppBar(
  50. centerTitle: true,
  51. elevation: 0,
  52. title: Text('排行榜'),
  53. ),
  54. body: Stack(
  55. children: <Widget>[
  56. RefreshIndicator(
  57. onRefresh: () async {
  58. await refresh();
  59. return;
  60. },
  61. child: Builder(
  62. builder: (context) {
  63. List<Widget> list = [
  64. Container(
  65. padding: EdgeInsets.only(bottom: 10),
  66. color: SUB_COLOR,
  67. child: Row(
  68. children: <Widget>[
  69. topRank(data.length > 1 ? data[1] : null),
  70. topRank(data.length > 0 ? data[0] : null),
  71. topRank(data.length > 2 ? data[2] : null),
  72. ],
  73. ),
  74. )
  75. ];
  76. if (data.length > 3) {
  77. for (int i = 3; i < data.length; i++) {
  78. list.add(rankItem(data[i]));
  79. }
  80. }
  81. return ListView(
  82. padding: EdgeInsets.only(bottom: 48),
  83. children: list,
  84. );
  85. },
  86. ),
  87. ),
  88. Align(
  89. alignment: Alignment.bottomCenter,
  90. child: rankItem(myParticipatingInfo, mine: true),
  91. )
  92. ],
  93. ),
  94. );
  95. }
  96. Widget topRank(ParticipatingInfo participatingInfo) {
  97. if (participatingInfo == null) {
  98. return Expanded(child: Container());
  99. }
  100. double size = participatingInfo.rank == 1 ? 80 : 70;
  101. List<Color> colors = [Color(0xFFD48E00), Color(0xFFFECF01)];
  102. String icon = 'images/icon_paihangbang_01.png';
  103. if (participatingInfo.rank == 2) {
  104. colors = [Color(0xFFC5C5C5), Color(0xFFE3E3E3)];
  105. icon = 'images/icon_paihangbang_02.png';
  106. } else if (participatingInfo.rank == 3) {
  107. colors = [Color(0xFFE77023), Color(0xFFF89E58)];
  108. icon = 'images/icon_paihangbang_03.png';
  109. }
  110. return Expanded(
  111. child: Container(
  112. margin: EdgeInsets.only(top: participatingInfo.rank == 1 ? 4 : 38),
  113. child: Column(
  114. children: <Widget>[
  115. Stack(
  116. children: <Widget>[
  117. Align(
  118. alignment: Alignment.topCenter,
  119. child: Container(
  120. width: size,
  121. height: size,
  122. margin: EdgeInsets.only(top: 23),
  123. padding: EdgeInsets.all(5),
  124. decoration: BoxDecoration(
  125. borderRadius: BorderRadius.all(Radius.circular(size / 2)),
  126. gradient: LinearGradient(
  127. colors: colors,
  128. begin: Alignment.centerRight,
  129. end: Alignment.centerLeft,
  130. ),
  131. ),
  132. child: ClipOval(
  133. child: CachedNetworkImage(
  134. imageUrl: participatingInfo?.userInfo?.icon ?? '',
  135. fit: BoxFit.cover,
  136. ),
  137. ),
  138. ),
  139. ),
  140. Align(
  141. alignment: Alignment.topCenter,
  142. child: Image.asset(icon),
  143. ),
  144. ],
  145. ),
  146. Container(
  147. margin: EdgeInsets.only(top: 6),
  148. child: Text(
  149. participatingInfo?.userInfo?.nickname ?? '',
  150. style: TextStyle(color: PRIMARY_COLOR, fontSize: 14, fontWeight: FontWeight.bold),
  151. ),
  152. ),
  153. Row(
  154. mainAxisSize: MainAxisSize.min,
  155. children: <Widget>[
  156. Image.asset('images/icon_jifen_da.png', width: 20),
  157. Container(
  158. margin: EdgeInsets.only(left: 2),
  159. child: Text(
  160. (participatingInfo?.points ?? 0).toString(),
  161. style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold),
  162. ),
  163. )
  164. ],
  165. )
  166. ],
  167. ),
  168. ),
  169. );
  170. }
  171. Widget rankItem(ParticipatingInfo participatingInfo, {bool mine = false}) {
  172. if (participatingInfo == null) {
  173. if (mine) {
  174. return Container();
  175. }
  176. return Container();
  177. }
  178. return Container(
  179. height: mine ? 48 : 66,
  180. decoration: BoxDecoration(
  181. border: Border(
  182. bottom: BorderSide(
  183. width: mine ? 0 : 1,
  184. color: Color(0x2E000000),
  185. ),
  186. ),
  187. color: mine ? SUB_COLOR : Colors.transparent,
  188. ),
  189. padding: EdgeInsets.only(left: 15),
  190. child: Row(
  191. children: <Widget>[
  192. Container(
  193. width: 30,
  194. height: 30,
  195. child: Stack(
  196. children: <Widget>[
  197. Image.asset('images/icon_rank.png'),
  198. Align(
  199. alignment: Alignment.topCenter,
  200. child: Container(
  201. margin: EdgeInsets.only(top: 11),
  202. child: Text(
  203. (participatingInfo?.rank ?? 0).toString(),
  204. style: TextStyle(color: Color(0xFF15151D), fontSize: 12, fontWeight: FontWeight.bold),
  205. ),
  206. ),
  207. )
  208. ],
  209. ),
  210. ),
  211. Container(
  212. width: mine ? 30 : 46,
  213. height: mine ? 30 : 46,
  214. margin: EdgeInsets.only(left: 10),
  215. child: ClipOval(
  216. child: CachedNetworkImage(
  217. imageUrl: participatingInfo?.userInfo?.icon ?? '',
  218. fit: BoxFit.cover,
  219. ),
  220. ),
  221. ),
  222. Expanded(
  223. child: Container(
  224. margin: EdgeInsets.only(left: 19),
  225. child: Text(
  226. participatingInfo?.userInfo?.nickname ?? '',
  227. style: TextStyle(color: mine ? Colors.white : PRIMARY_COLOR, fontSize: 14),
  228. ),
  229. ),
  230. ),
  231. Container(
  232. width: 113,
  233. child: Row(
  234. children: <Widget>[
  235. Image.asset('images/icon_jifen_da.png', width: 20),
  236. Container(
  237. margin: EdgeInsets.only(left: 2),
  238. child: Text(
  239. (participatingInfo?.points ?? 0).toString(),
  240. style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold),
  241. ),
  242. )
  243. ],
  244. ),
  245. )
  246. ],
  247. ),
  248. );
  249. }
  250. }