import 'dart:convert'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:sport/bean/rank_game_info.dart'; import 'package:sport/bean/user.dart'; import 'package:sport/provider/user_model.dart'; import 'package:sport/router/navigator_util.dart'; import 'package:sport/router/routes.dart'; import 'package:sport/services/api/inject_api.dart'; import 'package:sport/widgets/area.dart'; import 'package:sport/widgets/decoration.dart'; import 'package:sport/widgets/image.dart'; import 'package:sport/widgets/loading.dart'; import 'package:sport/widgets/space.dart'; class RankDetailPage extends StatefulWidget { final String id; final String type; RankDetailPage(this.id, this.type); @override State createState() { return _RankDetailPageState(); } } class _RankDetailPageState extends State with InjectApi { bool _isLoading; RankGameInfoData _data; String _id; String _rank; @override void initState() { super.initState(); // 简单的缓存... if (_data == null || _id != widget.id) { _isLoading = true; initData(); _id = widget.id; } else { _isLoading = false; } } // 缓存数据... initData() async { if (widget.type == "1") { api.getRankGameInfo(widget.id).then((data) { setState(() { _data = data.data; _isLoading = false; }); }); } else { api.getRankSportInfo(widget.id).then((data) { setState(() { _data = data.data; _isLoading = false; }); }); } } area(bool all, bool province, int provinceId, int cityId) { setState(() { _isLoading = true; }); if (widget.type == "1") { api.getRankGameInfo(widget.id, provinceId: all ? null : provinceId, cityId: all ? null : province ? null : cityId).then((data) { setState(() { _data = data.data; _isLoading = false; }); }); } else { api.getRankSportInfo(widget.id, provinceId: all ? null : provinceId, cityId: all ? null : province ? null : cityId).then((data) { setState(() { _data = data.data; _isLoading = false; }); }); } } initUser(int rank) { return User(position: rank, userName: '虚位以待', score: 0, id: 0); } Widget _buildRankWidget() { dynamic user1 = initUser(1), user2 = initUser(2), user3 = initUser(3), user4; if (_data != null && _data.records != null) { for (var i = 0; i < _data.records.length; i++) { var item = _data.records[i]; if (i == 0) { user1 = item; } else if (i == 1) { user2 = item; } else if (i == 2) { user3 = item; } } } return Column( children: [ Center( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.end, children: [ Container(width: 94, child: user2 != null ? _buildRankHeaderWidget(user2) : _buildRankHeaderWidget(initUser(2))), Container(width: 120, child: user1 != null ? _buildRankHeaderWidget(user1) : _buildRankHeaderWidget(initUser(1))), Container(width: 94, child: user3 != null ? _buildRankHeaderWidget(user3) : _buildRankHeaderWidget(initUser(3))), ], ), ), Space( height: 10, ), Divider( height: 1, indent: 12, endIndent: 12, ) ], ); } Widget _buildRankHeaderWidget(User user) { int rank = user.position; return InkWell( child: Column( children: [ rank == 1 ? Stack( alignment: Alignment.center, children: [ CircleAvatar(backgroundImage: userAvatarProvider(user.userAvatar == null ? "" : user.userAvatar), radius: 46.0), Image.asset( "lib/assets/img/rank_image_no$rank.png", ) ], ) : Stack( alignment: Alignment.topCenter, children: [ Positioned(top: 3, child: CircleAvatar(backgroundImage: userAvatarProvider(user.userAvatar == null ? "" : user.userAvatar), radius: 35.0)), Image.asset( "lib/assets/img/rank_image_no$rank.png", ) ], ), Space( height: 6, ), Text( "${user.userName}", style: Theme.of(context).textTheme.subtitle1, maxLines: 1, ), Space( height: 4, ), _dataText(_data.rank, user) ], ), onTap: () { if (user.id != 0) NavigatorUtil.goRankPeopleDetails(context, details: user); }, ); } Widget _buildRankItemWidget(int number, User data) { return Column( children: [ InkWell( onTap: () { if (data is User) { if (data.id != 0) NavigatorUtil.goRankPeopleDetails(context, details: data); } }, child: Container( padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 6.0), child: Row( children: [ Container( width: 20, child: Text( "$number", style: Theme.of(context).textTheme.bodyText2, ), ), Padding( padding: const EdgeInsets.fromLTRB(0, 6, 10.0, 6), child: CircleAvatar(backgroundColor:Colors.transparent, backgroundImage: userAvatarProvider(data.userAvatar == null ? "" : data.userAvatar), radius: 22), ), Expanded( child: Text( data.userName, style: Theme.of(context).textTheme.subtitle1, maxLines: 1, ), ), _dataText(_data.rank, data), ], ), ), ), Divider( height: 1, indent: 12, endIndent: 12, ), ], ); } List getRankItems() { List rankItems = []; if (_data != null && _data.records != null) { for (var i = 3; i < _data.records.length; i++) { var item = _data.records[i]; rankItems.add(_buildRankItemWidget(i + 1, item)); } } if (rankItems.length < 7) { int start = rankItems.length; for (var i = start; i < 7; i++) { var item = initUser(i + 4); rankItems.add(_buildRankItemWidget(i + 4, item)); } } return rankItems; } Widget getUserRank() { return Positioned( bottom: -36.0, left: 12.0, right: 12.0, child: Container( width: MediaQuery.of(context).size.width * 0.95, height: 72.0, decoration: card(), child: Padding( padding: EdgeInsets.symmetric(horizontal: 12.0), child: Row( children: [ _data.user != null ? Container( padding: EdgeInsets.only(right: 8), child: Text( "${_data.user.position}", style: Theme.of(context).textTheme.bodyText2, ), ) : Container(), _data.user != null ? _data.user.up != 0 && _data.user.upNew != 0 ? Padding( padding: EdgeInsets.only(right: 8), child: Image.asset("lib/assets/img/rand_icon_${_data.user.up >= 0 ? 'top' : 'down'}.png"), ) : Container() : Container(), Expanded( child: Container( child: Consumer( builder: (_, model, __) { return Row( mainAxisSize: MainAxisSize.max, children: [ CircleAvatar(backgroundImage: userAvatarProvider(model?.user?.avatar != null ? model.user.avatar : ""), radius: 22), SizedBox( width: 10, ), Expanded( child: Text( model.user.name, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.subtitle1, ), ), SizedBox( width: 10, ), ], ); }, ), ), ), _data.user == null ? Text("暂无记录", style: Theme.of(context).textTheme.bodyText1,) : _data.rank.userCountMax < _data.user.position ? Text("暂未上榜", style: Theme.of(context).textTheme.bodyText1,) : _dataText(_data.rank, _data.user), Container( width: 12.0, height: 14.0, margin: EdgeInsets.only(left: 18.0), child: Image.asset( "lib/assets/img/rank_icon_location.png", fit: BoxFit.cover, ), ), ], ), ), ), ); } Widget _dataText(Rank rank, User user) { var unit = _dataUnit(rank); if (rank != null) { if (rank.field == null || rank.field == "") { return Text(user.score == null || user.score == 0 ? "" : "${user.score.toStringAsFixed(1)}$unit", style: TextStyle(color: Color.fromRGBO(255, 196, 0, 1))); } else { if (rank.field == 'consume') { return Text(user.consume == null ? "" : "${user.consume.round()}$unit", style: TextStyle(color: Color.fromRGBO(255, 196, 0, 1))); } else if (rank.field == 'duration') { return Text(user.duration == null ? "" : "${user.duration}$unit", style: TextStyle(color: Color.fromRGBO(255, 196, 0, 1))); } } } return Container(); } String _dataUnit(Rank rank) { if (rank != null) { if (rank.field == null || rank.field == "") { return "分"; } else { if (rank.field == 'consume') { return "kal"; } else if (rank.field == 'duration') { return "分钟"; } } } return ""; } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: SingleChildScrollView( child: Column( children: [ //header Stack( overflow: Overflow.visible, children: [ Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.width * 611 / 1125, decoration: BoxDecoration(image: DecorationImage(image: AssetImage("lib/assets/img/rank_bg.png"), fit: BoxFit.fill)), child: SafeArea( child: Align( alignment: Alignment.centerLeft, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 12), child: _data?.rank == null ? Container() : Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Padding( padding: EdgeInsets.symmetric(vertical: 6.0), child: Text( "${_data.rank.name}", style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.w600), ), ), Padding( padding: EdgeInsets.symmetric(vertical: 2.0), child: Text( "${_data.rank.introduce}", style: Theme.of(context).textTheme.bodyText1, ), ), Padding( padding: EdgeInsets.symmetric(vertical: 2.0), child: Text( "${_data.rank.rateBegin} ~ ${_data.rank.rateEnd}", style: Theme.of(context).textTheme.bodyText1, ), ), SizedBox( height: 10, ) ], ), ), ), )), if (_data != null) getUserRank(), Positioned( left: 0.0, top: 0.0, child: SafeArea( child: IconButton( icon: Image.asset("lib/assets/img/topbar_return_white.png"), onPressed: () { Navigator.pop(context); }, ), )), Positioned( top: 0, right: 0, child: SafeArea( child: IconButton( icon: Image.asset("lib/assets/img/topbar_problom.png"), onPressed: () { if(_data == null) return; NavigatorUtil.go(context, "${Routes.rankIntroduce}?data=${Uri.encodeComponent(json.encode(_data))}"); }, ), )) ], ), if (!_isLoading) Padding( padding: const EdgeInsets.only(top: 50.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Consumer( builder: (_, model, __) => model.user.city == null || _rank == "全国榜" || _rank == null ? Container() : Container( padding: EdgeInsets.symmetric(horizontal: 12.0), child: Row( children: [ Image.asset("lib/assets/img/rank_icon_position.png"), SizedBox( width: 6, ), Text( "${_rank == '全省榜' ? model.user?.province : model.user?.city}", style: Theme.of(context).textTheme.bodyText2, ) ], ), ), ), NotificationListener( onNotification: (n) { _rank = n.rank; area(n.all, n.province, n.provinceId, n.cityId); return true; }, child: AreaPage( area: _rank, ), ) ], ), ), if (_isLoading) Container(child: RequestLoadingWidget()), if (!_isLoading) Padding( padding: EdgeInsets.only(top: 12.0), child: _buildRankWidget(), ), if (!_isLoading) Column( children: getRankItems(), ) ], ), )); } }