sport_data_page.dart 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import 'dart:math';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/services.dart';
  4. import 'package:sport/pages/data/sport_data_calendar.dart';
  5. import 'package:sport/pages/data/sport_data_detail.dart';
  6. import 'package:sport/utils/date.dart';
  7. import 'package:sport/widgets/appbar.dart';
  8. import 'package:sport/widgets/round_tab_indicator.dart';
  9. import 'package:umeng_common_sdk/umeng_common_sdk.dart';
  10. class SportDataPage extends StatefulWidget {
  11. final int initialPage;
  12. const SportDataPage({Key? key, this.initialPage = 0}) : super(key: key);
  13. @override
  14. State<StatefulWidget> createState() => SportDataPageState();
  15. static SportDataPageState? of(BuildContext context) {
  16. return context.findAncestorStateOfType<SportDataPageState>();
  17. }
  18. }
  19. class SportDataPageState extends State<SportDataPage> {
  20. final List<String> TABS = ["日", "周", "月", "年"];
  21. int _page = 0;
  22. int _type = 0;
  23. int _sportType = 0;
  24. late PageController _pageController;
  25. DateTime? _selectDate;
  26. @override
  27. void initState() {
  28. _type = widget.initialPage;
  29. _pageController = PageController();
  30. super.initState();
  31. }
  32. Future showCalendar(DateTime time) async {
  33. DateTime? select = await showModalBottomSheet(
  34. context: context,
  35. shape: RoundedRectangleBorder(
  36. borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)),
  37. ),
  38. builder: (context) => SportDataCalendarPage(
  39. time: time,
  40. ));
  41. if (select != null) {
  42. _selectDate = select;
  43. _pageController.jumpToPage(getInitialPage());
  44. }
  45. }
  46. int getInitialPage(){
  47. DateTime? select = _selectDate;
  48. if(select == null)
  49. return 0;
  50. DateTime t = DateTime.now();
  51. DateTime now = DateTime(t.year, t.month, t.day);
  52. int page = 0;
  53. if (_type == 0) {
  54. page = now.difference(select).inDays.abs();
  55. } else if (_type == 1) {
  56. DateTime now = DateTime(t.year, t.month, t.day - t.weekday + 1);
  57. DateTime ss = DateTime(select.year, select.month, select.day - select.weekday + 1);
  58. page = (now.difference(ss).inDays.abs() / 7).round();
  59. } else if (_type == 2) {
  60. page = (now.year - select.year) * 12 + ( now.month - select.month);
  61. } else if (_type == 3) {
  62. page = now.year - select.year;
  63. }
  64. return page;
  65. }
  66. @override
  67. Widget build(BuildContext context) {
  68. var _bg = const Color(0xff241D19);
  69. return DefaultTabController(
  70. initialIndex: widget.initialPage,
  71. length: TABS.length,
  72. child: Scaffold(
  73. appBar: AppBar(
  74. leading: buildBackButton(context, white: true),
  75. systemOverlayStyle: SystemUiOverlayStyle.light,
  76. centerTitle: false,
  77. backgroundColor: _bg,
  78. title: Container(
  79. height: 40,
  80. color: _bg,
  81. padding: const EdgeInsets.only(right: kMinInteractiveDimension),
  82. child: Center(
  83. child: TabBar(
  84. isScrollable: false,
  85. labelColor: Colors.white,
  86. labelStyle: const TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600, height: 1.2),
  87. unselectedLabelColor: Color(0xff999999),
  88. unselectedLabelStyle: const TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600, height: 1.2),
  89. indicatorSize: TabBarIndicatorSize.label,
  90. indicator: RoundUnderlineTabIndicator(borderSide: BorderSide(color: Theme.of(context).indicatorColor, width: 3), width: 0),
  91. onTap: (index) {
  92. setState(() {
  93. _type = index;
  94. _selectDate = null;
  95. _page = 0;
  96. _pageController = PageController(initialPage: _page);
  97. });
  98. UmengCommonSdk.onEvent("sport_data_date_type_$index", {});
  99. },
  100. tabs: TABS
  101. .map((e) => Tab(
  102. text: e,
  103. ))
  104. .toList(),
  105. ),
  106. ),
  107. ),
  108. actions: [
  109. Container()
  110. // GestureDetector(
  111. // onTap: () {},
  112. // child: Image.asset("lib/assets/img/bbs_icon_share.png", color: Colors.white),
  113. // ),
  114. ],
  115. ),
  116. body: NotificationListener(
  117. onNotification: (details) {
  118. if (details is PageNotification) {
  119. if (details.page > 0) {
  120. _pageController.animateToPage(min(10240,++_page), duration: Duration(milliseconds: 500), curve: Curves.linear);
  121. } else {
  122. _pageController.animateToPage(max(0,--_page), duration: Duration(milliseconds: 500), curve: Curves.linear);
  123. }
  124. } else if (details is SportTypeNotification) {
  125. _sportType = details.index;
  126. }
  127. return true;
  128. },
  129. child: PageView.builder(
  130. key: ValueKey("${_type}_${_selectDate?.toString()}"),
  131. controller: _pageController,
  132. // physics: NeverScrollableScrollPhysics(),
  133. onPageChanged: (page){
  134. _page = page;
  135. },
  136. reverse: true,
  137. itemCount: 10240,
  138. itemBuilder: (context, index) {
  139. var type = _type;
  140. var time = offsetDate(type, -index);
  141. return SportDataDetailPage(
  142. type: type,
  143. sportType: _sportType,
  144. time: time,
  145. index: index,
  146. selectDate: _selectDate,
  147. );
  148. },
  149. ),
  150. )),
  151. );
  152. }
  153. }
  154. class PageNotification extends Notification {
  155. PageNotification({
  156. required this.page,
  157. });
  158. final int page;
  159. }
  160. class SportTypeNotification extends Notification {
  161. SportTypeNotification({
  162. required this.index,
  163. });
  164. final int index;
  165. }