RankList.dart 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. import 'package:flutter/material.dart';
  2. import '../styles/colors.dart';
  3. import 'dart:ui';
  4. import '../styles/totast.dart';
  5. import '../model/PlayerInfo.dart';
  6. import '../net/HttpManager.dart';
  7. import '../net/Result.dart';
  8. import 'package:flutter_redux/flutter_redux.dart';
  9. import '../redux/AppState.dart';
  10. import '../model/CompetitionSeason.dart';
  11. class RankList extends StatefulWidget {
  12. RankList({Key key, this.raceId, this.gameId}) : super(key: key);
  13. final int raceId; // 用来储存传递过来的值
  14. final int gameId;
  15. @override
  16. RankListState createState() => RankListState();
  17. }
  18. class RankListState extends State<RankList> {
  19. String raceName = '2019';
  20. List raceNameList = ['2019', '2018', '2017'];
  21. List<PlayerInfo> rankList = [];
  22. ScrollController _mcontroller;
  23. bool scrollFlag = true;
  24. int currentPage = 1;
  25. int raceId = 0;
  26. List<CompetitionSeason> seasonList = [];
  27. PlayerInfo myPlayInfo;
  28. Future<void> getUserRank() async {
  29. Result res = await HttpManager.get('playerInfo/seasonUserRank', data: {
  30. 'seasonId': raceId,
  31. 'userId': StoreProvider.of<AppState>(context).state.userInfo.id,
  32. 'gameId': widget.gameId
  33. });
  34. if (res.success && res.data != null) {
  35. setState(() {
  36. myPlayInfo = PlayerInfo.fromJson(res.data);
  37. });
  38. } else {
  39. setState(() {
  40. myPlayInfo = null;
  41. });
  42. }
  43. currentPage = 1;
  44. getListPage();
  45. }
  46. Future<void> getListPage() async {
  47. scrollFlag = false;
  48. Toast.show(context, '加载中', -1, 'loading');
  49. Result res = await HttpManager.get('playerInfo/seasonRankPage', data: {
  50. 'seasonId': raceId,
  51. 'currentPage': currentPage,
  52. 'pageNumber': 20
  53. });
  54. Toast.hide();
  55. List<PlayerInfo> list = rankList;
  56. if (currentPage == 1) {
  57. list = [];
  58. }
  59. if (res.success) {
  60. for (var item in res.data['pp']) {
  61. PlayerInfo tip = PlayerInfo.fromJson(item);
  62. list.add(tip);
  63. }
  64. if (res.data['page']['currentPage'] < res.data['page']['totalPage']) {
  65. scrollFlag = true;
  66. }
  67. } else {}
  68. setState(() {
  69. rankList = list;
  70. });
  71. if (rankList.isNotEmpty) {
  72. showBackDialog();
  73. }
  74. }
  75. //没有赛季排行数据弹窗
  76. void showBackDialog() {
  77. showDialog<Null>(
  78. context: context,
  79. barrierDismissible: false,
  80. builder: (BuildContext context) {
  81. return AlertDialog(
  82. content: Container(
  83. height: 50,
  84. child: Text(
  85. '该赛季暂未产生排行数据,尽情期待...',
  86. style: TextStyle(color: Colors.black),
  87. ),
  88. ),
  89. actions: <Widget>[
  90. FlatButton(
  91. child: Text('确定'),
  92. onPressed: () {
  93. Navigator.of(context).pop();
  94. },
  95. ),
  96. ],
  97. );
  98. },
  99. ).then((val) {
  100. Navigator.of(context).pop();
  101. });
  102. }
  103. Future<void> getSeasonInfo() async {
  104. Result res = await HttpManager.get('competitionSeason/all');
  105. if (res.success) {
  106. List<CompetitionSeason> list = [];
  107. for (var item in res.data) {
  108. list.add(CompetitionSeason.fromJson(item));
  109. }
  110. setState(() {
  111. seasonList = list;
  112. });
  113. } else {}
  114. }
  115. @override
  116. void initState() {
  117. raceId = widget.raceId;
  118. super.initState();
  119. _mcontroller = ScrollController();
  120. _mcontroller.addListener(() {
  121. if (_mcontroller.position.pixels ==
  122. _mcontroller.position.maxScrollExtent) {
  123. if (scrollFlag) {
  124. currentPage++;
  125. getListPage();
  126. }
  127. }
  128. });
  129. Future.delayed(Duration.zero, () {
  130. getUserRank();
  131. getSeasonInfo();
  132. });
  133. }
  134. @override
  135. void dispose() {
  136. super.dispose();
  137. _mcontroller.dispose();
  138. }
  139. @override
  140. Widget build(BuildContext context) {
  141. return WillPopScope(
  142. child: Scaffold(
  143. body: Container(
  144. color: BG_SUB_COLOR,
  145. child: RefreshIndicator(
  146. color: PRIMARY_COLOR,
  147. backgroundColor: Colors.white,
  148. onRefresh: () async {
  149. await Future.delayed(const Duration(seconds: 1));
  150. getUserRank();
  151. },
  152. child: CustomScrollView(
  153. controller: _mcontroller,
  154. physics: AlwaysScrollableScrollPhysics(),
  155. slivers: <Widget>[
  156. _sliverAppBar(),
  157. _slievrToBoxAdapter(),
  158. _sliverList()
  159. ],
  160. )),
  161. ),
  162. floatingActionButton: myPlayInfo == null
  163. ? Container()
  164. : Container(
  165. padding: EdgeInsets.only(left: 20, right: 15),
  166. height: 48,
  167. decoration: BoxDecoration(
  168. gradient: LinearGradient(
  169. begin: Alignment.topRight,
  170. colors: [Color(0xFF59607A), Color(0xFF3C3C67)],
  171. )),
  172. child: Row(
  173. children: <Widget>[
  174. Container(
  175. width: 30,
  176. height: 30,
  177. child: CircleAvatar(
  178. backgroundImage:
  179. NetworkImage(myPlayInfo.userInfo.icon ?? '')),
  180. ),
  181. Padding(
  182. padding: EdgeInsets.symmetric(horizontal: 10),
  183. child: Text(myPlayInfo.userInfo.nickname ?? '',
  184. style:
  185. TextStyle(color: Colors.white, fontSize: 14)),
  186. ),
  187. Image.asset('images/icon_jinbi_da_bai.png', width: 20),
  188. Padding(
  189. padding: EdgeInsets.only(left: 2),
  190. child: Text((myPlayInfo.points ?? 0).toString(),
  191. style: TextStyle(
  192. color: Colors.white,
  193. fontSize: 14,
  194. fontWeight: FontWeight.bold)),
  195. ),
  196. myPlayInfo.rank == null
  197. ? Container()
  198. : Expanded(
  199. flex: 1,
  200. child: Text(
  201. '第 ' + myPlayInfo.rank.toString() + ' 名',
  202. style: TextStyle(
  203. color: Colors.white,
  204. fontSize: 14,
  205. fontWeight: FontWeight.bold),
  206. textAlign: TextAlign.right),
  207. )
  208. ],
  209. ),
  210. ),
  211. floatingActionButtonLocation:
  212. FloatingActionButtonLocation.centerDocked,
  213. ),
  214. onWillPop: () {
  215. Toast.hide();
  216. Navigator.pop(context);
  217. return Future.value(false);
  218. });
  219. }
  220. Widget _sliverAppBar() {
  221. CompetitionSeason competitionSeason;
  222. for (var item in seasonList) {
  223. if (item.id == raceId) {
  224. competitionSeason = item;
  225. }
  226. }
  227. return SliverAppBar(
  228. title: Text('排行榜'),
  229. centerTitle: true,
  230. actions: <Widget>[
  231. PopupMenuButton(
  232. initialValue: raceId,
  233. child: Row(
  234. crossAxisAlignment: CrossAxisAlignment.center,
  235. mainAxisAlignment: MainAxisAlignment.center,
  236. children: <Widget>[
  237. Text(
  238. competitionSeason != null ? competitionSeason.season : '',
  239. style: TextStyle(
  240. color: Colors.white,
  241. fontSize: 13,
  242. fontWeight: FontWeight.normal),
  243. ),
  244. Image.asset(
  245. 'images/icon_zhankai_baise.png',
  246. width: 20,
  247. ),
  248. Container(
  249. width: 15,
  250. )
  251. ],
  252. ),
  253. onSelected: (value) {
  254. setState(() {
  255. raceId = value;
  256. });
  257. getUserRank();
  258. },
  259. itemBuilder: (BuildContext context) {
  260. return seasonList.map((choice) {
  261. return PopupMenuItem(
  262. child: Text(choice.season), value: choice.id);
  263. }).toList();
  264. }),
  265. ],
  266. pinned: true);
  267. }
  268. Widget _slievrToBoxAdapter() {
  269. return SliverToBoxAdapter(
  270. child: Container(
  271. margin: EdgeInsets.only(bottom: 10),
  272. height: 196,
  273. color: PRIMARY_COLOR,
  274. child: Row(
  275. mainAxisAlignment: MainAxisAlignment.center,
  276. children: widgetList(),
  277. ),
  278. ),
  279. );
  280. }
  281. Widget _sliverList() {
  282. return SliverList(
  283. delegate: SliverChildBuilderDelegate(
  284. (BuildContext context, int index) {
  285. if (index > 2 && index < rankList.length) {
  286. return Container(
  287. padding: EdgeInsets.symmetric(horizontal: 15),
  288. child: Container(
  289. height: 36,
  290. decoration: BoxDecoration(
  291. border: Border(
  292. bottom: BorderSide(
  293. width: 1,
  294. color: Colors.black26,
  295. style: BorderStyle.solid))),
  296. child: Row(
  297. children: <Widget>[
  298. Container(
  299. width: 36,
  300. height: 36,
  301. margin: EdgeInsets.only(right: 15),
  302. child: CircleAvatar(
  303. backgroundImage:
  304. NetworkImage(rankList[index].userInfo.icon),
  305. ),
  306. ),
  307. Expanded(
  308. flex: 1,
  309. child: Column(
  310. mainAxisAlignment: MainAxisAlignment.center,
  311. crossAxisAlignment: CrossAxisAlignment.start,
  312. children: <Widget>[
  313. Text(rankList[index].userInfo.nickname,
  314. style: TextStyle(
  315. color: PRIMARY_COLOR,
  316. fontSize: 14,
  317. height: 1.2),
  318. overflow: TextOverflow.ellipsis),
  319. Row(
  320. children: <Widget>[
  321. Image.asset('images/icon_jinbi_da_bai.png',
  322. width: 20),
  323. Padding(
  324. padding: EdgeInsets.only(left: 2),
  325. child: Text(rankList[index].points.toString(),
  326. style: TextStyle(
  327. color: Colors.white,
  328. fontSize: 14,
  329. fontWeight: FontWeight.bold,
  330. )),
  331. )
  332. ],
  333. )
  334. ],
  335. ),
  336. ),
  337. index < 100
  338. ? Container(
  339. width: 30,
  340. height: 30,
  341. margin: EdgeInsets.only(right: 33),
  342. decoration: BoxDecoration(
  343. image: DecorationImage(
  344. image: AssetImage(
  345. 'images/icon_paihangbang_04.png'),
  346. fit: BoxFit.cover)),
  347. child: Text(
  348. rankList[index].rank.toString(),
  349. style: TextStyle(
  350. color: Color(0xFF15151D),
  351. fontSize: 12,
  352. fontWeight: FontWeight.bold,
  353. height: 2),
  354. textAlign: TextAlign.center,
  355. ),
  356. )
  357. : Container()
  358. ],
  359. ),
  360. ),
  361. height: 66,
  362. );
  363. } else if (index == rankList.length) {
  364. return Padding(
  365. padding: EdgeInsets.only(top: 10, bottom: 68),
  366. child: Text(
  367. '没有更多了',
  368. textAlign: TextAlign.center,
  369. style: TextStyle(color: Colors.white30),
  370. ),
  371. );
  372. } else {
  373. return Container();
  374. }
  375. },
  376. childCount: rankList.length + 1,
  377. ),
  378. );
  379. }
  380. List<Widget> widgetList() {
  381. List<Widget> list = [];
  382. if (rankList.isNotEmpty) {
  383. list.add(Container(
  384. margin: EdgeInsets.only(top: 0, left: 30, right: 30),
  385. child: Stack(
  386. children: <Widget>[
  387. Column(
  388. children: <Widget>[
  389. Container(
  390. margin: EdgeInsets.only(top: 25),
  391. width: 80,
  392. height: 80,
  393. child: Container(
  394. padding: EdgeInsets.all(5),
  395. width: 80,
  396. height: 80,
  397. decoration: BoxDecoration(
  398. borderRadius: BorderRadius.all(Radius.circular(80)),
  399. gradient: LinearGradient(
  400. begin: Alignment.topLeft,
  401. colors: [Color(0xFFFECF01), Color(0xFFD48E00)],
  402. ),
  403. boxShadow: [
  404. BoxShadow(
  405. color: Colors.black12,
  406. offset: Offset(2.0, 4.0),
  407. blurRadius: 4.0)
  408. ]),
  409. child: CircleAvatar(
  410. backgroundImage:
  411. NetworkImage(rankList[0].userInfo.icon))),
  412. ),
  413. Padding(
  414. padding: EdgeInsets.only(top: 7, bottom: 3),
  415. child: Text(rankList[0].userInfo.nickname,
  416. style: TextStyle(color: Color(0xFF2E3049), fontSize: 14)),
  417. ),
  418. Row(
  419. children: <Widget>[
  420. Padding(
  421. padding: EdgeInsets.only(right: 2),
  422. child: Image.asset('images/icon_jinbi_da_bai.png',
  423. width: 20),
  424. ),
  425. Text(rankList[0].points.toString(),
  426. style: TextStyle(
  427. color: Colors.white,
  428. fontSize: 14,
  429. fontWeight: FontWeight.bold))
  430. ],
  431. )
  432. ],
  433. ),
  434. Positioned(
  435. top: 0,
  436. left: 24,
  437. child: Image.asset('images/icon_paihangbang_01.png', width: 32))
  438. ],
  439. ),
  440. ));
  441. }
  442. if (rankList.length > 1) {
  443. list.insert(
  444. 0,
  445. Container(
  446. margin: EdgeInsets.only(top: 25),
  447. child: Stack(
  448. children: <Widget>[
  449. Column(
  450. children: <Widget>[
  451. Container(
  452. margin: EdgeInsets.only(top: 25),
  453. width: 70,
  454. height: 70,
  455. child: Stack(
  456. children: <Widget>[
  457. Container(
  458. padding: EdgeInsets.all(5),
  459. width: 70,
  460. height: 70,
  461. decoration: BoxDecoration(
  462. borderRadius:
  463. BorderRadius.all(Radius.circular(70)),
  464. gradient: LinearGradient(
  465. begin: Alignment.topLeft,
  466. colors: [
  467. Color(0xFFE3E3E3),
  468. Color(0xFFC5C5C5)
  469. ],
  470. ),
  471. boxShadow: [
  472. BoxShadow(
  473. color: Colors.black12,
  474. offset: Offset(2.0, 4.0),
  475. blurRadius: 4.0)
  476. ]),
  477. child: CircleAvatar(
  478. backgroundImage: NetworkImage(
  479. rankList[1].userInfo.icon))),
  480. ],
  481. ),
  482. ),
  483. Padding(
  484. padding: EdgeInsets.only(top: 7, bottom: 3),
  485. child: Text(rankList[1].userInfo.nickname,
  486. style: TextStyle(
  487. color: Color(0xFF2E3049), fontSize: 14)),
  488. ),
  489. Row(
  490. children: <Widget>[
  491. Padding(
  492. padding: EdgeInsets.only(right: 2),
  493. child: Image.asset('images/icon_jinbi_da_bai.png',
  494. width: 20),
  495. ),
  496. Text(rankList[1].points.toString(),
  497. style: TextStyle(
  498. color: Colors.white,
  499. fontSize: 14,
  500. fontWeight: FontWeight.bold))
  501. ],
  502. )
  503. ],
  504. ),
  505. Positioned(
  506. top: 0,
  507. left: 19,
  508. child: Image.asset('images/icon_paihangbang_02.png',
  509. width: 32))
  510. ],
  511. )));
  512. }
  513. if (rankList.length > 2) {
  514. list.add(Container(
  515. margin: EdgeInsets.only(top: 25),
  516. child: Stack(
  517. children: <Widget>[
  518. Column(
  519. children: <Widget>[
  520. Container(
  521. width: 70,
  522. height: 70,
  523. margin: EdgeInsets.only(top: 25),
  524. child: Stack(
  525. children: <Widget>[
  526. Container(
  527. padding: EdgeInsets.all(5),
  528. width: 70,
  529. height: 70,
  530. decoration: BoxDecoration(
  531. borderRadius:
  532. BorderRadius.all(Radius.circular(70)),
  533. gradient: LinearGradient(
  534. begin: Alignment.topLeft,
  535. colors: [
  536. Color(0xFFF89E58),
  537. Color(0xFFE77023)
  538. ],
  539. ),
  540. boxShadow: [
  541. BoxShadow(
  542. color: Colors.black12,
  543. offset: Offset(2.0, 4.0),
  544. blurRadius: 4.0)
  545. ]),
  546. child: CircleAvatar(
  547. backgroundImage:
  548. NetworkImage(rankList[2].userInfo.icon))),
  549. ],
  550. ),
  551. ),
  552. Padding(
  553. padding: EdgeInsets.only(top: 7, bottom: 3),
  554. child: Text(rankList[2].userInfo.nickname,
  555. style:
  556. TextStyle(color: Color(0xFF2E3049), fontSize: 14)),
  557. ),
  558. Row(
  559. children: <Widget>[
  560. Padding(
  561. padding: EdgeInsets.only(right: 2),
  562. child: Image.asset('images/icon_jinbi_da_bai.png',
  563. width: 20),
  564. ),
  565. Text(rankList[2].points.toString(),
  566. style: TextStyle(
  567. color: Colors.white,
  568. fontSize: 14,
  569. fontWeight: FontWeight.bold))
  570. ],
  571. )
  572. ],
  573. ),
  574. Positioned(
  575. top: 0,
  576. left: 19,
  577. child:
  578. Image.asset('images/icon_paihangbang_03.png', width: 32))
  579. ],
  580. )));
  581. }
  582. if (rankList.length<=1) {
  583. list.insert(0,Container(
  584. // margin: EdgeInsets.only(top: 50),
  585. child: Container(
  586. width: 70,
  587. height: 70,
  588. ),
  589. ));
  590. }
  591. if (rankList.length<=2) {
  592. list.add(Container(
  593. // margin: EdgeInsets.only(top: 50),
  594. child: Container(
  595. width: 70,
  596. height: 70,
  597. ),
  598. ));
  599. }
  600. return list;
  601. }
  602. }