Hibok
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

812 wiersze
28 KiB

  1. import 'package:chat/data/UserData.dart';
  2. import 'package:chat/data/WebData.dart';
  3. import 'package:chat/generated/i18n.dart';
  4. import 'package:chat/home/ProfilePage.dart';
  5. import 'package:chat/home/rich_title.dart';
  6. import 'package:chat/models/ref_name_provider.dart';
  7. import 'package:chat/utils/CustomUI.dart';
  8. import 'package:chat/utils/HttpUtil.dart';
  9. import 'package:chat/utils/MessageMgr.dart';
  10. import 'package:chat/utils/PicSwiper.dart';
  11. import 'package:chat/utils/TokenMgr.dart';
  12. import 'package:chat/utils/conversation_table.dart';
  13. import 'package:chat/utils/friend_list_mgr.dart';
  14. import 'package:chat/utils/screen.dart';
  15. import 'package:dio/dio.dart';
  16. import 'package:flutter/cupertino.dart';
  17. import 'package:flutter/material.dart';
  18. import 'package:flutter/services.dart';
  19. import 'package:oktoast/oktoast.dart';
  20. import 'package:provider/provider.dart';
  21. import 'package:pull_to_refresh/pull_to_refresh.dart';
  22. import 'package:url_launcher/url_launcher.dart';
  23. import '../data/constants.dart' show AppColors, Constants;
  24. import '../data/conversation.dart';
  25. import 'package:cached_network_image/cached_network_image.dart';
  26. import 'ProgramDetail.dart';
  27. class _ConversationItem extends StatelessWidget {
  28. const _ConversationItem(
  29. {Key key,
  30. this.conversation,
  31. this.callback,
  32. this.showRight = true,
  33. this.rightButton,
  34. this.applyInfo,
  35. this.bgColor,
  36. this.title})
  37. : assert(conversation != null),
  38. super(key: key);
  39. final Widget rightButton;
  40. final Conversation conversation;
  41. final callback;
  42. final bool showRight;
  43. final title;
  44. final applyInfo;
  45. final bgColor;
  46. @override
  47. Widget build(BuildContext context) {
  48. Widget avatar;
  49. double width = 53;
  50. if (conversation.isAvatarFromNet()) {
  51. avatar = ClipRRect(
  52. borderRadius: BorderRadius.circular(10),
  53. child: CachedNetworkImage(
  54. imageUrl: conversation.avatar,
  55. placeholder: (context, url) => Image.asset(
  56. Constants.DefaultHeadImgUrl,
  57. width: width,
  58. height: width,
  59. ),
  60. fit: BoxFit.cover,
  61. width: width,
  62. height: width,
  63. ));
  64. } else {
  65. avatar = ClipRRect(
  66. borderRadius: BorderRadius.circular(10),
  67. child: Container(
  68. width: width,
  69. height: width,
  70. alignment: Alignment.center,
  71. decoration: BoxDecoration(
  72. gradient: this.bgColor,
  73. borderRadius: BorderRadius.all(Radius.circular(50))),
  74. child: Image.asset(
  75. conversation.avatar,
  76. height: 27,
  77. )));
  78. }
  79. _buildBotton(str, callback) {
  80. return InkWell(
  81. onTap: callback,
  82. child: Container(
  83. padding: EdgeInsets.only(top: 5, left: 15, right: 15, bottom: 5),
  84. decoration: BoxDecoration(
  85. border:
  86. Border.all(color: Constants.ConfrimButtonColor, width: 1),
  87. color: Constants.ConfrimButtonColor,
  88. borderRadius: BorderRadius.all(Radius.circular(5))),
  89. child: fixedText(
  90. str,
  91. fontSize: 12,
  92. color: Colors.white,
  93. ),
  94. ));
  95. }
  96. void doApply(state, callback) async {
  97. Map data = {
  98. "id": applyInfo['applyId'],
  99. "userId": UserData().basicInfo.userId,
  100. "status": state,
  101. };
  102. data['sign'] = TokenMgr().getSign(data);
  103. Response res = await HttpUtil().post('user/handler/apply', data: data);
  104. if (res == null) {
  105. return;
  106. }
  107. var resData = res.data;
  108. if (resData['code'] == 0) {
  109. callback(resData['msg']);
  110. } else {}
  111. }
  112. void doFriendApply(state, callback) async {
  113. Map data = {
  114. "id": applyInfo['applyId'],
  115. "userId": UserData().basicInfo.userId,
  116. "status": state,
  117. };
  118. data['sign'] = TokenMgr().getSign(data);
  119. Response res =
  120. await HttpUtil().post('friendship/handler/apply', data: data);
  121. if (res == null) {
  122. return;
  123. }
  124. var resData = res.data;
  125. if (resData['code'] == 0) {
  126. callback(resData['msg']);
  127. } else {}
  128. }
  129. var bottomWiget = applyInfo == null
  130. ? Container()
  131. : Container(
  132. padding: EdgeInsets.only(left: 0, top: 10),
  133. decoration: BoxDecoration(
  134. color: Color(AppColors.ConversationItemBgColor),
  135. ),
  136. child: Row(
  137. crossAxisAlignment: CrossAxisAlignment.center,
  138. children: applyInfo['type'] == 0 || applyInfo['type'] == 6
  139. ? <Widget>[
  140. CustomUI.buildImgCover(
  141. applyInfo['imgId'],
  142. [
  143. PicSwiperItem(applyInfo['showUrl'],
  144. id: applyInfo['imgId'],
  145. type: applyInfo['type'] == 0
  146. ? PhotoType.destroy.index
  147. : PhotoType.free.index,
  148. isWatch: applyInfo['isWatch'],
  149. userId: applyInfo['userId'])
  150. ],
  151. applyInfo['showUrl'],
  152. 65,
  153. 10,
  154. applyInfo['isWatch'],
  155. context,
  156. applyInfo['type'] == 0
  157. ? PhotoType.destroy.index
  158. : PhotoType.free.index),
  159. Expanded(
  160. child: applyInfo['type'] == 0
  161. ? Container(
  162. alignment: Alignment.centerRight,
  163. padding: EdgeInsets.only(top: 40),
  164. child: applyInfo['state'] == 0
  165. ? Row(
  166. mainAxisAlignment:
  167. MainAxisAlignment.end,
  168. children: <Widget>[
  169. _buildBotton(I18n.of(context).aging,
  170. () {
  171. doApply(1, (msg) {
  172. showToast(msg);
  173. applyInfo['state'] = 1;
  174. MessageMgr()
  175. .emit('do_info_apply');
  176. });
  177. }),
  178. SizedBox(
  179. width: 10,
  180. ),
  181. _buildBotton(I18n.of(context).refuse,
  182. () {
  183. doApply(2, (msg) {
  184. showToast(msg);
  185. applyInfo['state'] = 2;
  186. MessageMgr()
  187. .emit('do_info_apply');
  188. });
  189. }),
  190. ],
  191. )
  192. : Padding(
  193. padding: EdgeInsets.only(right: 0),
  194. child: Text(
  195. applyInfo['state'] == 1
  196. ? I18n.of(context).passed
  197. : I18n.of(context).rejected,
  198. style: TextStyle(
  199. color: Constants.GreyTextColor,
  200. fontSize: 13),
  201. textScaleFactor: 1.0,
  202. ),
  203. ),
  204. )
  205. : Container(),
  206. )
  207. ]
  208. : [
  209. Expanded(child: Container()),
  210. Container(
  211. alignment: Alignment.centerRight,
  212. child: applyInfo['state'] == 0
  213. ? Row(
  214. mainAxisAlignment: MainAxisAlignment.end,
  215. children: <Widget>[
  216. _buildBotton(I18n.of(context).agree, () {
  217. doFriendApply(1, (msg) {
  218. showToast(msg);
  219. applyInfo['state'] = 1;
  220. var friendModel =
  221. FriendModel.fromServerJson({
  222. 'UserId': applyInfo['userId'],
  223. 'ImgUrl': applyInfo['imgUrl'],
  224. 'UserName': applyInfo['name']
  225. });
  226. FriendListMgr().addFriend(friendModel);
  227. MessageMgr().emit('do_info_apply');
  228. MessageMgr().emit('do_friend_apply', {
  229. 'userId': applyInfo['userId'],
  230. 'state': 1
  231. });
  232. MessageMgr().emit('Add friend');
  233. });
  234. }),
  235. SizedBox(
  236. width: 10,
  237. ),
  238. _buildBotton(I18n.of(context).refuse, () {
  239. doFriendApply(2, (msg) {
  240. showToast(msg);
  241. applyInfo['state'] = 2;
  242. MessageMgr().emit('do_info_apply');
  243. MessageMgr().emit('do_friend_apply', {
  244. 'userId': applyInfo['userId'],
  245. 'state': 2
  246. });
  247. });
  248. }),
  249. ],
  250. )
  251. : Padding(
  252. padding: EdgeInsets.only(right: 0),
  253. child: Text(
  254. applyInfo['state'] == 1
  255. ? I18n.of(context).passed
  256. : I18n.of(context).rejected,
  257. style: TextStyle(
  258. color: Constants.GreyTextColor,
  259. fontSize: 13),
  260. textScaleFactor: 1.0,
  261. ),
  262. ),
  263. ),
  264. ],
  265. ),
  266. );
  267. return InkWell(
  268. child: Container(
  269. padding:
  270. const EdgeInsets.only(left: 16.5, top: 11, bottom: 11, right: 14.5),
  271. decoration: BoxDecoration(
  272. color: Color(AppColors.ConversationItemBgColor),
  273. border: Border(
  274. bottom: BorderSide(
  275. color: AppColors.DividerColor,
  276. width: Constants.DividerWidth))),
  277. child: Column(
  278. children: <Widget>[
  279. Row(
  280. crossAxisAlignment: CrossAxisAlignment.start,
  281. children: <Widget>[
  282. avatar,
  283. Container(width: 19.0),
  284. Expanded(
  285. child: Container(
  286. child: Column(
  287. crossAxisAlignment: CrossAxisAlignment.start,
  288. children: <Widget>[
  289. Container(
  290. child: title == null
  291. ? Text(conversation.title,
  292. textScaleFactor: 1.0,
  293. style: TextStyle(
  294. fontSize: 12,
  295. color: Constants.LightGreyTextColor))
  296. : title),
  297. Container(
  298. padding: EdgeInsets.only(top: 5, bottom: 5),
  299. child: Row(
  300. children: <Widget>[
  301. Text(conversation.desc,
  302. textScaleFactor: 1.0,
  303. style: TextStyle(
  304. fontSize: 11,
  305. color: Constants.LightGreyTextColor)),
  306. showRight
  307. ? Expanded(
  308. child: Container(
  309. alignment: Alignment.centerRight,
  310. child: rightButton == null
  311. ? Text(
  312. '${I18n.of(context).go_see}>',
  313. textScaleFactor: 1.0,
  314. style: TextStyle(
  315. fontSize: 11,
  316. color: Constants
  317. .LightGreyTextColor))
  318. : rightButton,
  319. ),
  320. )
  321. : Container()
  322. ],
  323. )),
  324. applyInfo != null && applyInfo['content'] != null
  325. ? Container(
  326. child: Text(applyInfo['content'],
  327. textScaleFactor: 1.0,
  328. style: TextStyle(
  329. fontSize: 14,
  330. color: Constants.LightGreyTextColor)))
  331. : Container(),
  332. ],
  333. ),
  334. )),
  335. ],
  336. ),
  337. bottomWiget
  338. ],
  339. ),
  340. ),
  341. onTap: () {
  342. callback();
  343. },
  344. );
  345. }
  346. }
  347. class InfoListPage extends StatefulWidget {
  348. @required
  349. final String title;
  350. @required
  351. final int type;
  352. InfoListPage({Key key, this.title = "", this.type = 1}) : super(key: key);
  353. _InfoListPageState createState() => _InfoListPageState();
  354. }
  355. class _InfoListPageState extends State<InfoListPage>
  356. with SingleTickerProviderStateMixin {
  357. List list = new List(); //列表要展示的数据
  358. RefreshController _refreshController =
  359. RefreshController(initialRefresh: true);
  360. int _page = 1; //加载的页数
  361. int rows = 20;
  362. @override
  363. void initState() {
  364. super.initState();
  365. messageOn();
  366. }
  367. void initList(data) {
  368. list.clear();
  369. if (data != null) {
  370. list.addAll(data);
  371. }
  372. if (mounted) setState(() {});
  373. }
  374. void addList(data) {
  375. if (data == null || data.length == 0) {
  376. _page--;
  377. _refreshController.loadNoData();
  378. } else {
  379. list.addAll(data);
  380. _refreshController.loadComplete();
  381. }
  382. setState(() {});
  383. }
  384. messageApply(data) {
  385. _onRefresh();
  386. }
  387. msgPhoto(id) {
  388. for (int i = 0; i < list.length; i++) {
  389. if (list[i]['ApplyImg'] == id) {
  390. setState(() {
  391. list[i]['IsCheck'] = 1;
  392. });
  393. break;
  394. }
  395. }
  396. }
  397. void messageOn() {
  398. MessageMgr().on('do_info_apply', messageApply);
  399. MessageMgr().on('refresh_photo', msgPhoto);
  400. }
  401. void messageOff() {
  402. MessageMgr().off('do_info_apply', messageApply);
  403. MessageMgr().off('refresh_photo', msgPhoto);
  404. }
  405. getNewData(callback) {
  406. switch (widget.type) {
  407. case InfoType.Apply: //获取申请通知
  408. getData('user/check/realecords', callback);
  409. break;
  410. case InfoType.Evaluation: //获取评价通知
  411. getData('evaluate/user/realecordslist', callback);
  412. break;
  413. case InfoType.System: //获取系统通知
  414. getData('message/center/list', callback);
  415. break;
  416. case InfoType.Radio: //获取电台消息
  417. getData('message/center/cast', callback);
  418. break;
  419. case InfoType.Money: //获取钱包通知
  420. getData('message/wallet/message', callback);
  421. break;
  422. default:
  423. }
  424. }
  425. Future getData(url, callback) async {
  426. Map data = {
  427. "userId": UserData().basicInfo.userId,
  428. };
  429. if (widget.type == InfoType.System) {
  430. data['type'] = UserData().basicInfo.sex;
  431. }
  432. data['sign'] = TokenMgr().getSign(data);
  433. if (widget.type == InfoType.Money) {
  434. data['type'] = 1;
  435. }
  436. data["page"] = _page;
  437. data['rows'] = rows;
  438. Response res = await HttpUtil()
  439. .post(url, data: data, failback: () => Navigator.of(context).pop());
  440. _refreshController.refreshCompleted();
  441. var resData = res.data;
  442. print(resData);
  443. if (resData['code'] == 0) {
  444. callback(resData['data']);
  445. } else {
  446. showToast(resData['msg']);
  447. }
  448. }
  449. /*
  450. * 下拉刷新方法,为list重新赋值
  451. */
  452. Future<Null> _onRefresh() async {
  453. _page = 1;
  454. getNewData(initList);
  455. }
  456. @override
  457. void dispose() {
  458. _refreshController.dispose();
  459. messageOff();
  460. super.dispose();
  461. }
  462. //钱包通知
  463. Widget _buildMoneyInfo(data) {
  464. String imgUrl = data['HeadImg'] == null || data['HeadImg'] == ''
  465. ? 'assets/images/chat/icon4.png'
  466. : data['HeadImg'];
  467. bool showIndex = data['ChangeUserId'] != 0;
  468. return _ConversationItem(
  469. conversation: Conversation(
  470. avatar: imgUrl,
  471. title: '',
  472. desc: WebData().getLoginTime(context, data['CreateTime']),
  473. updateAt: '',
  474. ),
  475. bgColor: Constants.MoneyGradient,
  476. showRight: data['DetailType'] == 10,
  477. title: RichTitle.getRichTitleWidget(data, context, InfoType.Money),
  478. rightButton: Text(I18n.of(context).alreay_back,
  479. style: TextStyle(
  480. fontSize: 12,
  481. fontWeight: FontWeight.normal,
  482. color: Constants.BlackTextColor)),
  483. callback: () {
  484. if (showIndex) {
  485. Navigator.of(context).push(
  486. new MaterialPageRoute(
  487. builder: (context) {
  488. return ProfilePage(
  489. userId: data['UserId'] == UserData().basicInfo.userId
  490. ? data['ChangeUserId']
  491. : data['UserId'],
  492. );
  493. },
  494. ),
  495. );
  496. }
  497. },
  498. );
  499. }
  500. //申请列表
  501. Widget _buildApllayInfo(userInfo) {
  502. bool isMyself = userInfo['ApplyUserId'] == UserData().basicInfo.userId;
  503. String name = isMyself ? userInfo['UserName'] : userInfo['ApplyName'];
  504. String imgUrl = isMyself ? userInfo['UserUrl'] : userInfo['ApplyUrl'];
  505. var applyInfo = {
  506. 'applyId': userInfo['Id'],
  507. 'userId': userInfo['ApplyUserId'],
  508. 'name': name,
  509. 'type': userInfo['Type'],
  510. 'imgUrl': imgUrl,
  511. 'showUrl': userInfo['ImgUrl'],
  512. 'content': userInfo['Content'],
  513. 'imgId': userInfo['ApplyImg'],
  514. 'createTime': userInfo['CreatTime'],
  515. 'isWatch': userInfo['IsCheck'] == 1,
  516. 'state': userInfo['Status'],
  517. };
  518. return _ConversationItem(
  519. conversation: Conversation(
  520. avatar: imgUrl == null || imgUrl == ''
  521. ? Constants.DefaultHeadImgUrl
  522. : imgUrl,
  523. title: '',
  524. desc: WebData().getLoginTime(context, userInfo['CreatTime']),
  525. updateAt: '17:20',
  526. ),
  527. title: RichTitle.getRichTitleWidget(userInfo, context, InfoType.Apply),
  528. applyInfo: isMyself ? null : applyInfo,
  529. callback: () {
  530. Navigator.of(context).push(
  531. new MaterialPageRoute(
  532. builder: (context) {
  533. return ProfilePage(
  534. userId: isMyself ? userInfo['UserId'] : userInfo['ApplyUserId'],
  535. );
  536. },
  537. ),
  538. );
  539. },
  540. );
  541. }
  542. //评价列表
  543. Widget _buildContentInfo(userInfo) {
  544. Widget botton = InkWell(
  545. onTap: () async {
  546. var data = {
  547. "userid": UserData().basicInfo.userId,
  548. "evaluateuserid": userInfo['EvaluateUserId'],
  549. };
  550. data['sign'] = TokenMgr().getSign(data);
  551. Response res =
  552. await HttpUtil().post('evaluate/user/appeal', data: data);
  553. if (res == null) {
  554. return;
  555. }
  556. Map resData = res.data;
  557. if (resData['code'] == 0) {
  558. setState(() {
  559. userInfo['Status'] = 1;
  560. });
  561. }
  562. },
  563. child: Container(
  564. padding: EdgeInsets.only(top: 2, left: 5, right: 5, bottom: 2),
  565. decoration: BoxDecoration(
  566. border:
  567. Border.all(color: Constants.LightBlueButtonColor, width: 1),
  568. color: Constants.LightBlueButtonColor,
  569. borderRadius: BorderRadius.all(Radius.circular(5))),
  570. child: fixedText(
  571. I18n.of(context).appeal,
  572. fontSize: 9,
  573. color: Colors.white,
  574. ),
  575. ));
  576. return _ConversationItem(
  577. conversation: Conversation(
  578. avatar: 'assets/images/chat/icon6.png',
  579. title: '',
  580. desc: WebData().getLoginTime(context, userInfo['CreateTime']),
  581. updateAt: '17:20',
  582. ),
  583. bgColor: Constants.EvaGradient,
  584. rightButton: userInfo['Status'] == 0 || userInfo['Status'] == 3
  585. ? botton
  586. : Text(userInfo['Status'] == 1 ? I18n.of(context).appealed : "",
  587. style:
  588. TextStyle(fontSize: 11, color: Constants.LightGreyTextColor)),
  589. title:
  590. RichTitle.getRichTitleWidget(userInfo, context, InfoType.Evaluation),
  591. callback: () {},
  592. );
  593. }
  594. String getReportTilte(bool isMyself, data) {
  595. String res = '';
  596. switch (data['ReportType']) {
  597. //举报用户
  598. case 1:
  599. if (isMyself) {
  600. res = data['Status'] == 1
  601. ? I18n.of(context)
  602. .report_success
  603. .replaceFirst('/s1', data['ReportedUserName'])
  604. : I18n.of(context)
  605. .report_failure
  606. .replaceFirst('/s1', data['ReportedUserName']);
  607. } else {
  608. res = I18n.of(context).coin_returen;
  609. }
  610. break;
  611. //举报节目
  612. case 2:
  613. break;
  614. //举报动态
  615. case 3:
  616. break;
  617. //举报评论
  618. case 4:
  619. break;
  620. default:
  621. }
  622. return res;
  623. }
  624. //系统通知
  625. Widget _buildSystemInfo(data) {
  626. bool isMyself = data['UserId'] == UserData().basicInfo.userId;
  627. String imgUrl = data['Type'] == 3
  628. ? (isMyself ? data['HeadImg'] : 'assets/images/chat/icon5.png')
  629. : 'assets/images/chat/icon5.png';
  630. var applyInfo = {
  631. 'applyId': data['Id'],
  632. 'userId': data['ApplyUserId'],
  633. 'name': data['Theme'],
  634. 'type': data['Type'],
  635. 'imgUrl': imgUrl,
  636. 'showUrl': data['HeadImg'],
  637. 'content': data['Content'],
  638. 'imgId': data['ApplyImg'],
  639. 'createTime': data['CreatTime'],
  640. 'isWatch': data['IsCheck'] == 1,
  641. 'links': data['Links'],
  642. 'state': data['Status'],
  643. };
  644. return _ConversationItem(
  645. conversation: Conversation(
  646. avatar: imgUrl,
  647. title: '',
  648. desc: WebData().getLoginTime(context, data['CreateTime']),
  649. updateAt: '17:20',
  650. ),
  651. showRight: data['Type'] == 6,
  652. applyInfo: data['Type'] == 6 ? applyInfo : null, // applyInfo,
  653. bgColor: Constants.ParkGradient,
  654. title: data['Type'] == 6
  655. ? Text(data['Theme'])
  656. : RichTitle.getRichTitleWidget(data, context, InfoType.System),
  657. callback: () {
  658. if (data['Type'] == 4 && data['Status'] == 1) {
  659. ClipboardData clipboardData =
  660. new ClipboardData(text: data['Content']);
  661. Clipboard.setData(clipboardData);
  662. showToast(I18n.of(context).successful_copy);
  663. }
  664. if (data['Type'] == 3) {
  665. Navigator.of(context).push(
  666. new MaterialPageRoute(
  667. builder: (context) {
  668. return ProfilePage(
  669. userId: data['ReportedUserId'],
  670. );
  671. },
  672. ),
  673. );
  674. }
  675. if (data['Type'] == 6) {
  676. launch(applyInfo['links']);
  677. }
  678. },
  679. );
  680. }
  681. //电台消息
  682. Widget _buildRadioInfo(data) {
  683. String imgUrl = data['HeadImg'] == null || data['HeadImg'] == ''
  684. ? Constants.DefaultHeadImgUrl
  685. : data['HeadImg'];
  686. return _ConversationItem(
  687. conversation: Conversation(
  688. avatar: imgUrl,
  689. title: '',
  690. desc: WebData().getLoginTime(context, data['CreateTime']),
  691. updateAt: '17:20',
  692. ),
  693. title: RichTitle.getRichTitleWidget(data, context, InfoType.Radio),
  694. callback: () {
  695. Navigator.of(context).push(
  696. new MaterialPageRoute(
  697. builder: (context) {
  698. return ProgramDetailPage(
  699. programId: data['Id'],
  700. );
  701. },
  702. ),
  703. );
  704. },
  705. );
  706. }
  707. Widget _renderRow(BuildContext context, int index) {
  708. if (index < list.length) {
  709. var userInfo = list[index];
  710. Widget result = Container();
  711. switch (widget.type) {
  712. case InfoType.Apply:
  713. result = _buildApllayInfo(userInfo);
  714. break;
  715. case InfoType.Evaluation:
  716. result = _buildContentInfo(userInfo);
  717. break;
  718. case InfoType.System:
  719. result = _buildSystemInfo(userInfo);
  720. break;
  721. case InfoType.Radio:
  722. result = _buildRadioInfo(userInfo);
  723. break;
  724. case InfoType.Money:
  725. result = _buildMoneyInfo(userInfo);
  726. break;
  727. default:
  728. }
  729. if (index == 0) {
  730. result = Padding(padding: EdgeInsets.only(top: 10), child: result);
  731. }
  732. return result;
  733. }
  734. return Container();
  735. }
  736. void _onLoading() async {
  737. _page++;
  738. getNewData(addList);
  739. }
  740. @override
  741. Widget build(BuildContext context) {
  742. var content = Scaffold(
  743. appBar: AppBar(
  744. backgroundColor: AppColors.NewAppbarBgColor,
  745. title: Text(
  746. widget.title,
  747. style: TextStyle(color: AppColors.NewAppbarTextColor),
  748. ),
  749. leading: CustomUI.buildCustomLeading(context),
  750. centerTitle: true,
  751. ),
  752. body: SafeArea(
  753. child: SmartRefresher(
  754. enablePullDown: true,
  755. enablePullUp: true,
  756. header: MaterialClassicHeader(),
  757. footer: CustomUI.buildLoadingFooter(),
  758. controller: _refreshController,
  759. onRefresh: _onRefresh,
  760. onLoading: _onLoading,
  761. child: (_refreshController.headerStatus == RefreshStatus.completed &&
  762. list.length == 0)
  763. ? CustomUI.buildNoData(context)
  764. : ListView.builder(
  765. itemBuilder: _renderRow,
  766. itemCount: list.length,
  767. ),
  768. )));
  769. return content; // CustomUI.buildPageLoading(context, content, !isLoadingFish);
  770. }
  771. }