NewsListPage.dart 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_osc/model/api.dart';
  4. import 'dart:convert';
  5. import 'package:flutter_osc/model/constants.dart';
  6. import 'package:flutter_osc/pages/news_detail_page.dart';
  7. import 'package:flutter_osc/util/NetUtils.dart';
  8. import 'package:flutter_osc/widgets/CommonEndLine.dart';
  9. import 'package:flutter_osc/widgets/SlideView.dart';
  10. class NewsListPage extends StatefulWidget {
  11. @override
  12. State<StatefulWidget> createState() {
  13. return NewsListPageState();
  14. }
  15. }
  16. class NewsListPageState extends State<NewsListPage> {
  17. var listData;
  18. var slideData;
  19. var curPage = 1;
  20. int? listTotalSize = 0;
  21. ScrollController _controller = ScrollController();
  22. TextStyle titleTextStyle = TextStyle(fontSize: 15.0);
  23. TextStyle subtitleStyle = TextStyle(color: const Color(0xFFB5BDC0), fontSize: 12.0);
  24. NewsListPageState() {
  25. _controller.addListener(() {
  26. var maxScroll = _controller.position.maxScrollExtent;
  27. var pixels = _controller.position.pixels;
  28. if (maxScroll == pixels && listData.length < listTotalSize) {
  29. // scroll to bottom, get next page data
  30. print("load more ... ");
  31. curPage++;
  32. getNewsList(true);
  33. }
  34. });
  35. }
  36. @override
  37. void initState() {
  38. super.initState();
  39. getNewsList(false);
  40. }
  41. Future<Null> _pullToRefresh() async {
  42. curPage = 1;
  43. getNewsList(false);
  44. return null;
  45. }
  46. @override
  47. Widget build(BuildContext context) {
  48. if (listData == null) {
  49. return Center(
  50. child: CircularProgressIndicator(),
  51. );
  52. } else {
  53. Widget listView = ListView.builder(
  54. itemCount: listData.length * 2,
  55. itemBuilder: (context, i) => renderRow(i),
  56. controller: _controller,
  57. );
  58. return RefreshIndicator(child: listView, onRefresh: _pullToRefresh);
  59. }
  60. }
  61. getNewsList(bool isLoadMore) {
  62. String url = Api.NEWS_LIST;
  63. url += "?pageIndex=$curPage&pageSize=10";
  64. print("newsListUrl: $url");
  65. NetUtils.get(url).then((data) {
  66. if (data != null) {
  67. Map<String, dynamic> map = json.decode(data);
  68. if (map['code'] == 0) {
  69. var msg = map['msg'];
  70. listTotalSize = msg['news']['total'];
  71. var _listData = msg['news']['data'];
  72. var _slideData = msg['slide'];
  73. setState(() {
  74. if (!isLoadMore) {
  75. listData = _listData;
  76. slideData = _slideData;
  77. } else {
  78. List list1 = [];
  79. list1.addAll(listData);
  80. list1.addAll(_listData);
  81. if (list1.length >= listTotalSize!) {
  82. list1.add(Constants.END_LINE_TAG);
  83. }
  84. listData = list1;
  85. slideData = _slideData;
  86. }
  87. });
  88. }
  89. }
  90. });
  91. }
  92. Widget renderRow(i) {
  93. if (i == 0) {
  94. return Container(
  95. height: 180.0,
  96. child: SlideView(slideData),
  97. );
  98. }
  99. i -= 1;
  100. if (i.isOdd) {
  101. return Divider(height: 1.0);
  102. }
  103. i = i ~/ 2;
  104. var itemData = listData[i];
  105. if (itemData is String && itemData == Constants.END_LINE_TAG) {
  106. return CommonEndLine();
  107. }
  108. var titleRow = Row(
  109. children: [
  110. Expanded(
  111. child: Text(itemData['title'], style: titleTextStyle),
  112. )
  113. ],
  114. );
  115. var timeRow = Row(
  116. children: [
  117. Container(
  118. width: 20.0,
  119. height: 20.0,
  120. decoration: BoxDecoration(
  121. shape: BoxShape.circle,
  122. color: const Color(0xFFECECEC),
  123. image: DecorationImage(
  124. image: NetworkImage(itemData['authorImg']), fit: BoxFit.cover),
  125. border: Border.all(
  126. color: const Color(0xFFECECEC),
  127. width: 2.0,
  128. ),
  129. ),
  130. ),
  131. Padding(
  132. padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
  133. child: Text(
  134. itemData['timeStr'],
  135. style: subtitleStyle,
  136. ),
  137. ),
  138. Expanded(
  139. flex: 1,
  140. child: Row(
  141. mainAxisAlignment: MainAxisAlignment.end,
  142. children: [
  143. Text("${itemData['commCount']}", style: subtitleStyle),
  144. Image.asset('./images/ic_comment.png', width: 16.0, height: 16.0),
  145. ],
  146. ),
  147. )
  148. ],
  149. );
  150. var thumbImgUrl = itemData['thumb'];
  151. var thumbImg = Container(
  152. margin: const EdgeInsets.all(10.0),
  153. width: 60.0,
  154. height: 60.0,
  155. decoration: BoxDecoration(
  156. shape: BoxShape.circle,
  157. color: const Color(0xFFECECEC),
  158. image: DecorationImage(
  159. image: ExactAssetImage('./images/ic_img_default.jpg'),
  160. fit: BoxFit.cover),
  161. border: Border.all(
  162. color: const Color(0xFFECECEC),
  163. width: 2.0,
  164. ),
  165. ),
  166. );
  167. if (thumbImgUrl != null && thumbImgUrl.length > 0) {
  168. thumbImg = Container(
  169. margin: const EdgeInsets.all(10.0),
  170. width: 60.0,
  171. height: 60.0,
  172. decoration: BoxDecoration(
  173. shape: BoxShape.circle,
  174. color: const Color(0xFFECECEC),
  175. image: DecorationImage(
  176. image: NetworkImage(thumbImgUrl), fit: BoxFit.cover),
  177. border: Border.all(
  178. color: const Color(0xFFECECEC),
  179. width: 2.0,
  180. ),
  181. ),
  182. );
  183. }
  184. var row = Row(
  185. children: [
  186. Expanded(
  187. flex: 1,
  188. child: Padding(
  189. padding: const EdgeInsets.all(10.0),
  190. child: Column(
  191. children: [
  192. titleRow,
  193. Padding(
  194. padding: const EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 0.0),
  195. child: timeRow,
  196. )
  197. ],
  198. ),
  199. ),
  200. ),
  201. Padding(
  202. padding: const EdgeInsets.all(6.0),
  203. child: Container(
  204. width: 100.0,
  205. height: 80.0,
  206. color: const Color(0xFFECECEC),
  207. child: Center(
  208. child: thumbImg,
  209. ),
  210. ),
  211. )
  212. ],
  213. );
  214. return InkWell(
  215. child: row,
  216. onTap: () {
  217. Navigator.of(context).push(MaterialPageRoute(
  218. builder: (ctx) => NewsDetailPage(id: itemData['detailUrl'])
  219. ));
  220. },
  221. );
  222. }
  223. }