完整代码如下:
    关键点做了注释

    1. import 'package:dianxue/pages/tabTwo/dealError/dealErrorDetail.dart';
    2. import 'package:flutter/material.dart';
    3. import 'package:dianxue/config/common.dart';
    4. import 'package:flutter_html/flutter_html.dart';
    5. import 'package:dianxue/config/global.dart' as global;
    6. class DealError extends StatefulWidget {
    7. DealError({Key key,}):super(key: key);
    8. DealErrorState createState() => DealErrorState();
    9. }
    10. class DealErrorState extends State<DealError> with SingleTickerProviderStateMixin {
    11. List<int> page = [1, 1];
    12. List _data = [[], []];
    13. List<bool> hasMore = [true, true];
    14. List<bool> isLoading = [false, false];
    15. List<String> tabs = ["待批改", "已批改"];
    16. int currentTab = 0;
    17. TabController _tabbarController; // 关键
    18. ScrollController scrollCtrl = ScrollController();
    19. void _loadMore() async{
    20. if(isLoading[currentTab] || !hasMore[currentTab]) return;
    21. setState(() {
    22. isLoading[currentTab] = true;
    23. });
    24. List<int> newData;
    25. await Future.delayed(Duration(seconds: 1), () {
    26. page[currentTab]++;
    27. newData = List<int>.generate(10, (index) => index);
    28. hasMore[currentTab] = page[currentTab] > 5 ? false : true;
    29. });
    30. _data[currentTab].addAll(newData);
    31. setState(() {
    32. page = page;
    33. hasMore = hasMore;
    34. isLoading[currentTab] = false;
    35. _data = _data;
    36. });
    37. }
    38. @override
    39. void initState() {
    40. super.initState();
    41. // 关键
    42. _tabbarController = new TabController(initialIndex: 0, length: tabs.length, vsync: this);
    43. _tabbarController.addListener(() {
    44. //关键 添加内容tab切换监听, 将变化同步到自定义的TabNav状态上
    45. setState(() {
    46. currentTab = _tabbarController.index;
    47. });
    48. if(page[_tabbarController.index] == 1) {
    49. _loadMore();
    50. }
    51. });
    52. _loadMore();
    53. scrollCtrl.addListener(() {
    54. if (scrollCtrl.position.pixels == scrollCtrl.position.maxScrollExtent) {
    55. _loadMore();
    56. }
    57. });
    58. }
    59. @override
    60. Widget build(BuildContext context) {
    61. return Scaffold(
    62. appBar: AppBar(
    63. centerTitle: true,
    64. title: Text('批改错题', style: TextStyle(fontSize: setFont(18), color: Color(0xffffffff), fontWeight: FontWeight.w800),),
    65. leading: goBackArr(context),
    66. elevation: 0,
    67. actions: <Widget>[
    68. GestureDetector(
    69. onTap: () {
    70. showMenu();
    71. },
    72. child: Container(
    73. width: setSize(36),
    74. alignment: Alignment.center,
    75. child: Image(image: getAssetImage('menu.png'), width: setSize(22), height: setSize(22), fit: BoxFit.fill,),
    76. )
    77. ),
    78. SizedBox(width: setSize(28),)
    79. ],
    80. ),
    81. body: Container(
    82. width: setFullWidth(context),
    83. height: setFullHeight(context),
    84. child: Column(
    85. mainAxisAlignment: MainAxisAlignment.start,
    86. crossAxisAlignment: CrossAxisAlignment.center,
    87. children: <Widget>[
    88. Container(
    89. width: setSize(310),
    90. height: setSize(33),
    91. decoration: BoxDecoration(
    92. gradient: LinearGradient(colors: [Color(0xFF569EFF), Color(0xFF48A2FF)]),
    93. borderRadius: BorderRadius.circular(6)
    94. ),
    95. child: Row(
    96. mainAxisAlignment: MainAxisAlignment.center,
    97. crossAxisAlignment: CrossAxisAlignment.center,
    98. children: tabs.map((e) => GestureDetector(
    99. onTap: () {
    100. int idx = tabs.indexOf(e);
    101. setState(() {
    102. currentTab = idx;
    103. });
    104. // 关键 将状态赋予tabBarView
    105. _tabbarController.index = currentTab;
    106. if(page[idx] == 1) {
    107. _loadMore();
    108. }
    109. },
    110. child: Container(
    111. width: setSize(150),
    112. height: setSize(27),
    113. decoration: BoxDecoration(
    114. color: currentTab == tabs.indexOf(e) ? Color.fromRGBO(255, 255, 255, 0.98) : Colors.transparent,
    115. borderRadius: BorderRadius.circular(6)
    116. ),
    117. alignment: Alignment.center,
    118. child: Text(e, style: TextStyle(fontSize: setFont(14), color: currentTab == tabs.indexOf(e) ? Color(0xff62aaff) : Colors.white, fontWeight: FontWeight.w600),),
    119. ),
    120. )
    121. ).toList()
    122. ),
    123. ),
    124. SizedBox(height: setSize(15),),
    125. Expanded(
    126. child: TabBarView(
    127. controller: _tabbarController,
    128. children: _data.map((e) {
    129. return e.length > 0 ? ListView.builder(
    130. itemCount: e.length + 1,
    131. physics: const AlwaysScrollableScrollPhysics(),
    132. controller: scrollCtrl,
    133. itemBuilder: (context, index) {
    134. if (index == e.length) {
    135. return loadMoreBottom(hasMore[currentTab]);
    136. } else {
    137. return GestureDetector(
    138. onTap: () {
    139. Navigator.of(global.homeContext).push(MaterialPageRoute(builder: (context) {
    140. return DealErrorDetail();
    141. }));
    142. },
    143. child: Column(
    144. mainAxisAlignment: MainAxisAlignment.start,
    145. crossAxisAlignment: CrossAxisAlignment.center,
    146. children: <Widget>[
    147. Container(
    148. padding: EdgeInsets.only(top: setSize(15)),
    149. margin: EdgeInsets.only(bottom: setSize(10)),
    150. decoration: BoxDecoration(
    151. color: Color(0xffffffff),
    152. ),
    153. child: Column(
    154. mainAxisAlignment: MainAxisAlignment.start,
    155. crossAxisAlignment: CrossAxisAlignment.center,
    156. children: <Widget>[
    157. Container(
    158. color: Colors.white,
    159. padding: EdgeInsets.symmetric(horizontal: setSize(40)),
    160. child: Html(
    161. data: '<h3>这道题好难啊!</h3><p> 阿兰德斯康啦是的</p><p>八十多分离开阿斯顿里卡多死了卡斯蒂略</p><p>hello world</p>',
    162. ),
    163. ),
    164. Container(
    165. height: setSize(40),
    166. padding: EdgeInsets.symmetric(horizontal: setSize(40)),
    167. child: Row(
    168. mainAxisAlignment: MainAxisAlignment.spaceBetween,
    169. crossAxisAlignment: CrossAxisAlignment.center,
    170. children: <Widget>[
    171. Container(
    172. height: setSize(20),
    173. padding: EdgeInsets.symmetric(horizontal: setSize(14)),
    174. decoration: BoxDecoration(
    175. color: Color.fromRGBO(255, 207, 117, 0.18),
    176. borderRadius: BorderRadius.circular(setSize(2)),
    177. boxShadow: [BoxShadow(blurRadius: setSize(20), color: Color.fromRGBO(255, 207, 117, 1), offset: Offset(0, setSize(20)), spreadRadius: setSize(-15))]
    178. ),
    179. alignment: Alignment.center,
    180. child: Text('数学', style: TextStyle(fontSize: setFont(10), color: Color(0xffff7f00), fontWeight: FontWeight.w800),),
    181. ),
    182. Text('36/120', style: TextStyle(fontSize: setFont(10), color: Color(0xffff7f00), fontWeight: FontWeight.w800),),
    183. ],
    184. )
    185. )
    186. ],
    187. ),
    188. ),
    189. Container(
    190. height: setSize(8),
    191. color: Color(0xfff4f4f4),
    192. )
    193. ],
    194. )
    195. );
    196. }
    197. },
    198. ) : (isLoading[currentTab] || _data.indexOf(e) != currentTab ?
    199. LoadingView(context: context,) :
    200. blankView(context, getAssetImage('blank_content.png'), '暂无内容哦~'));
    201. },).toList(),
    202. ),
    203. )
    204. ],
    205. )
    206. )
    207. );
    208. }
    209. }