YSSquareArticle.dart 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. import 'dart:math';
  2. import 'dart:ui';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/cupertino.dart';
  5. import 'package:flutter_easyrefresh/easy_refresh.dart';
  6. import 'package:ysairplane/tools/YSNetWorking.dart';
  7. import 'package:ysairplane/tools/YSTools.dart';
  8. const APPBAR_SCROLL_OFFSET = 100; //设置滑动变化的偏移量
  9. class YSSquareArticle extends StatefulWidget {
  10. final squareId,typeId;
  11. const YSSquareArticle({Key key, this.squareId, this.typeId}) : super(key: key);
  12. @override
  13. _YSSquareArticleState createState() => _YSSquareArticleState();
  14. }
  15. class _YSSquareArticleState extends State<YSSquareArticle> {
  16. ScrollController _scroll = ScrollController();
  17. double appBarAlpha = 0;
  18. double start = 0;
  19. double number = 0;
  20. int _page = 1;
  21. List _dataArray = [];
  22. _onScroll(offset) {
  23. double alpha = offset / APPBAR_SCROLL_OFFSET;
  24. if (alpha < 0) {
  25. alpha = 0;
  26. } else if (alpha > 1) {
  27. alpha = 1;
  28. }
  29. setState(() {
  30. appBarAlpha = alpha;
  31. });
  32. }
  33. Map _dict;
  34. @override
  35. void initState() {
  36. Future.delayed(Duration(seconds: 0)).then((value){
  37. _getSquareDetailData();
  38. });
  39. super.initState();
  40. }
  41. @override
  42. Widget build(BuildContext context) {
  43. return CupertinoPageScaffold(
  44. child: SingleChildScrollView(
  45. child: _dict==null?Container(
  46. height: MediaQuery.of(context).padding.top+44,
  47. padding: EdgeInsets.only(left: 15,right: 15,top: MediaQuery.of(context).padding.top),
  48. color: Colors.white,
  49. child: Row(
  50. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  51. children: [
  52. GestureDetector(
  53. onTap: (){
  54. Navigator.pop(context);
  55. },
  56. child: Icon(Icons.arrow_back_ios,size: 20,color: Color(0xFF000000),),
  57. ),
  58. Text('详情',style: TextStyle(fontSize: 18,color: Color(0xFF000000),decoration: TextDecoration.none),),
  59. Icon(Icons.share,size: 25,color: Color(0xFF000000),)
  60. ],
  61. ),
  62. ):Column(
  63. children: [
  64. Stack(
  65. children: [
  66. Container(
  67. height: MediaQuery.of(context).size.height-50,
  68. child: Listener(
  69. onPointerDown: (PointerDownEvent pointerDownEvent) {
  70. start = pointerDownEvent.position.dy;
  71. },
  72. onPointerMove: (PointerMoveEvent pointerMoveEvent) {
  73. setState(() {
  74. number = (pointerMoveEvent.position.dy-start)/5;
  75. });
  76. },
  77. onPointerUp: (PointerUpEvent upEvent) {
  78. setState(() {
  79. number = 0;
  80. });
  81. },
  82. child: NotificationListener(
  83. onNotification: (scrollNotification) {
  84. if (scrollNotification is ScrollUpdateNotification &&
  85. scrollNotification.depth == 0) {
  86. //滚动且是列表滚动的时候
  87. _onScroll(scrollNotification.metrics.pixels);
  88. return true;
  89. }else{
  90. return false;
  91. }
  92. },
  93. child: EasyRefresh(
  94. onRefresh: _getSquareDetailData,
  95. onLoad: _loadMore,
  96. header: MaterialHeader(
  97. ),
  98. footer: BezierBounceFooter(
  99. backgroundColor: Colors.transparent,
  100. color: Colors.transparent,
  101. ),
  102. child: SingleChildScrollView(
  103. controller: _scroll,
  104. padding: EdgeInsets.all(0),
  105. child: Stack(
  106. children: [
  107. Container(
  108. height: 240+number,
  109. width: MediaQuery.of(context).size.width,
  110. child: Image(
  111. image: NetworkImage('${_dict['topicCover']}'),
  112. fit: BoxFit.fill,
  113. ),
  114. ),
  115. Container(
  116. margin: EdgeInsets.only(top: 230+number),
  117. decoration: BoxDecoration(
  118. color: Colors.white,
  119. borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10))
  120. ),
  121. child: Column(
  122. children: [
  123. Container(
  124. height: 60,
  125. padding: EdgeInsets.only(left: 15,right: 15,top: 10,bottom: 10),
  126. child: Row(
  127. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  128. children: [
  129. Container(
  130. height: 40,
  131. width: 40,
  132. decoration: BoxDecoration(
  133. borderRadius: BorderRadius.all(Radius.circular(20)),
  134. image: DecorationImage(image: NetworkImage('${_dict['user']['avatar']}'),fit: BoxFit.fill)
  135. ),
  136. margin: EdgeInsets.only(right: 6),
  137. ),
  138. Column(
  139. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  140. children: [
  141. Container(
  142. width: MediaQuery.of(context).size.width-170,
  143. child: Text('${_dict['user']['nickname']}',style: TextStyle(fontSize: 14,color: Color(0xFF333333),decoration: TextDecoration.none),),
  144. ),
  145. Container(
  146. width: MediaQuery.of(context).size.width-170,
  147. child: Text('旅游达人',style: TextStyle(fontSize: 10,color: Color(0xFF999999),decoration: TextDecoration.none,fontWeight: FontWeight.normal),),
  148. )
  149. ],
  150. ),
  151. Container(
  152. height: 30,
  153. width: 65,
  154. child: Image.asset('lib/images/look.png'),
  155. ),
  156. ],
  157. ),
  158. ),
  159. Divider(
  160. height: 0.5,
  161. color: Color(0xFFE5E5E5),
  162. ),
  163. Container(
  164. width: MediaQuery.of(context).size.width,
  165. padding: EdgeInsets.only(top: 15,left: 10,right: 10,bottom: 15),
  166. child: Text('${_dict['topicTitle']}',style: TextStyle(fontSize: 17,color: Color(0xFF333333),decoration: TextDecoration.none),),
  167. ),
  168. Container(
  169. width: MediaQuery.of(context).size.width,
  170. padding: EdgeInsets.only(left: 10,right: 10,bottom: 15),
  171. child: Text('${_dict['topicContent']}',
  172. style: TextStyle(fontSize: 14,color: Color(0xFF666666),decoration: TextDecoration.none,fontWeight: FontWeight.normal),),
  173. ),
  174. Container(
  175. height: 10,
  176. color: Color(0xFFF1F2F4),
  177. margin: EdgeInsets.only(bottom: 10),
  178. ),
  179. Container(
  180. width: MediaQuery.of(context).size.width,
  181. padding: EdgeInsets.only(left: 10,right: 10,bottom: 15),
  182. child: Text('335210条评论',style: TextStyle(fontSize: 13,color: Color(0xFF666666),decoration: TextDecoration.none,fontWeight: FontWeight.normal),),
  183. ),
  184. Container(
  185. height: 50,
  186. padding: EdgeInsets.only(left: 10,right: 10,bottom: 10),
  187. child: Row(
  188. children: [
  189. Container(
  190. height: 40,
  191. width: 40,
  192. decoration: BoxDecoration(
  193. borderRadius: BorderRadius.all(Radius.circular(20)),
  194. color: Color(0xFF151515)
  195. ),
  196. ),
  197. GestureDetector(
  198. onTap: (){
  199. _showInputView();
  200. },
  201. child: Container(
  202. height: 40,
  203. margin: EdgeInsets.only(left: 10),
  204. padding: EdgeInsets.only(left: 10,right: 10),
  205. width: MediaQuery.of(context).size.width-80,
  206. decoration: BoxDecoration(
  207. borderRadius: BorderRadius.all(Radius.circular(20)),
  208. color: Color(0xFFF5F5F5)
  209. ),
  210. alignment: Alignment.centerLeft,
  211. child: Text('有爱评论,说点儿好听的~',style: TextStyle(fontSize: 14,color: Color(0xFF595959),decoration: TextDecoration.none,fontWeight: FontWeight.normal),)
  212. ),
  213. ),
  214. ],
  215. ),
  216. ),
  217. Container(
  218. child: ListView.separated(
  219. padding: EdgeInsets.only(top: 15),
  220. shrinkWrap: true,
  221. itemBuilder: (context,index){
  222. return Container(
  223. child: Column(
  224. children: [
  225. Container(
  226. padding: EdgeInsets.only(left: 10,right: 10,bottom: 10),
  227. child: Row(
  228. crossAxisAlignment: CrossAxisAlignment.start,
  229. children: [
  230. Container(
  231. height: 40,
  232. width: 40,
  233. decoration: BoxDecoration(
  234. borderRadius: BorderRadius.all(Radius.circular(20)),
  235. image: DecorationImage(image: NetworkImage('${_dataArray[index]['avatar']}'),fit: BoxFit.fill)
  236. ),
  237. ),
  238. Container(
  239. margin: EdgeInsets.only(left: 10),
  240. width: MediaQuery.of(context).size.width-70,
  241. child: Column(
  242. crossAxisAlignment: CrossAxisAlignment.start,
  243. children: [
  244. GestureDetector(
  245. child: Text('${_dataArray[index]['nickname']}',
  246. style: TextStyle(fontSize: 14,color: Color(0xFF3C61B1),decoration: TextDecoration.none,fontWeight: FontWeight.bold),),
  247. onTap: (){
  248. _showInputView(type: 1,toUserid: int.parse('${_dataArray[index]['fromUserId']}'),
  249. fatherCommentId: int.parse('${_dataArray[index]['id']}'),fromUserId: int.parse('${_dataArray[index]['fromUserId']}'));
  250. },
  251. ),
  252. Text('${_dataArray[index]['comment']}',style: TextStyle(fontSize: 15,color: Color(0xFF333333),decoration: TextDecoration.none,fontWeight: FontWeight.normal)),
  253. ],
  254. ),
  255. )
  256. ],
  257. ),
  258. ),
  259. Container(
  260. child: ListView.separated(
  261. itemBuilder: (context,indexSub){
  262. return Row(
  263. crossAxisAlignment: CrossAxisAlignment.start,
  264. children: [
  265. Container(
  266. height: 20,
  267. width: 20,
  268. decoration: BoxDecoration(
  269. borderRadius: BorderRadius.all(Radius.circular(20)),
  270. image: DecorationImage(image: NetworkImage('${_dataArray[index]['dtSquareCommentsList'][indexSub]['avatar']}'),fit: BoxFit.fill)
  271. ),
  272. ),
  273. Container(
  274. margin: EdgeInsets.only(left: 10),
  275. width: MediaQuery.of(context).size.width-130,
  276. child: Column(
  277. crossAxisAlignment: CrossAxisAlignment.start,
  278. children: [
  279. GestureDetector(
  280. child: Text('${_dataArray[index]['dtSquareCommentsList'][indexSub]['nickname']}',
  281. style: TextStyle(fontSize: 14,color: Color(0xFF3C61B1),decoration: TextDecoration.none,fontWeight: FontWeight.bold),),
  282. onTap: (){
  283. _showInputView(type: 1,toUserid: _dataArray[index]['dtSquareCommentsList'][indexSub]['fromUserId'],
  284. fatherCommentId: _dataArray[index]['dtSquareCommentsList'][indexSub]['fatherCommentId']);
  285. },
  286. ),
  287. RichText(
  288. text: TextSpan(
  289. style: TextStyle(fontSize: 14,color: Color(0xFF333333),decoration: TextDecoration.none,fontWeight: FontWeight.normal),
  290. text: '回复',
  291. children: [
  292. TextSpan(
  293. text: ' ${_dataArray[index]['dtSquareCommentsList'][indexSub]['otherNickname']}:',
  294. style: TextStyle(color: Color(0xFF3C61B1),fontWeight: FontWeight.bold)
  295. ),
  296. TextSpan(
  297. text: '${_dataArray[index]['dtSquareCommentsList'][indexSub]['comment']}',
  298. style: TextStyle(color: Color(0xFF333333))
  299. ),
  300. TextSpan(
  301. text: ' ${_dataArray[index]['dtSquareCommentsList'][indexSub]['timeNode']}',
  302. style: TextStyle(color: Color(0xFF999999),fontSize: 12)
  303. )
  304. ]
  305. ),
  306. )
  307. ],
  308. ),
  309. )
  310. ],
  311. );
  312. },
  313. separatorBuilder: (context,index){
  314. return Container(
  315. height: 5,
  316. );
  317. },
  318. itemCount: (_dataArray[index]['dtSquareCommentsList']).length,
  319. shrinkWrap: true,
  320. padding: EdgeInsets.only(left: 60,right: 40),
  321. physics: NeverScrollableScrollPhysics(),
  322. ),
  323. )
  324. ],
  325. ),
  326. );
  327. },
  328. separatorBuilder: (context,index){
  329. return Container(
  330. height: 5,
  331. );
  332. },
  333. itemCount: _dataArray.length,
  334. physics: NeverScrollableScrollPhysics(),
  335. ),
  336. )
  337. ],
  338. ),
  339. ),
  340. ],
  341. ),
  342. ),
  343. ),
  344. ),
  345. ),
  346. ),
  347. Container(
  348. height: MediaQuery.of(context).padding.top+44,
  349. padding: EdgeInsets.only(left: 15,right: 15,top: MediaQuery.of(context).padding.top),
  350. color: Colors.white.withOpacity(appBarAlpha),
  351. child: Row(
  352. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  353. children: [
  354. GestureDetector(
  355. onTap: (){
  356. Navigator.pop(context);
  357. },
  358. child: Icon(Icons.arrow_back_ios,size: 20,color: appBarAlpha>0.5?Color(0xFF000000):Colors.white,),
  359. ),
  360. if(appBarAlpha>0.5)Text('详情',style: TextStyle(fontSize: 18,color: Color(0xFF000000),decoration: TextDecoration.none),),
  361. Icon(Icons.share,size: 25,color: appBarAlpha>0.5?Color(0xFF000000):Colors.white,)
  362. ],
  363. ),
  364. )
  365. ],
  366. ),
  367. Container(
  368. height: 50,
  369. padding: EdgeInsets.only(left: 15,right: 15),
  370. color: Color(0xFFF5F5F5),
  371. child: Row(
  372. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  373. children: [
  374. Container(
  375. width: MediaQuery.of(context).size.width-120,
  376. padding: EdgeInsets.only(left: 15,right: 15),
  377. height: 30,
  378. decoration: BoxDecoration(
  379. color: Colors.white,
  380. borderRadius: BorderRadius.all(Radius.circular(15))
  381. ),
  382. child: Row(
  383. children: [
  384. GestureDetector(
  385. onTap: (){
  386. _showInputView(type: 0);
  387. },
  388. child: Container(
  389. width: MediaQuery.of(context).size.width-175,
  390. child: Text('我来说两句',style: TextStyle(fontSize: 14,color: Color(0xFF999999),decoration: TextDecoration.none,fontWeight: FontWeight.normal),),
  391. ),
  392. ),
  393. Icon(Icons.tag_faces,size: 25,color: Color(0xFFF5F5F5),),
  394. ],
  395. ),
  396. ),
  397. GestureDetector(
  398. onTap: (){
  399. _postAgreementData(1);
  400. },
  401. child: Container(
  402. height: 20,
  403. width: 20,
  404. child: Image.asset(_dict==null?'lib/images/love.png':_dict['likeStatus']==1?'lib/images/love2.png':'lib/images/love.png'),
  405. ),
  406. ),
  407. GestureDetector(
  408. child: Icon(_dict==null?Icons.star_border:_dict['collectStatus']==1?Icons.star:Icons.star_border,size: 20,color: Color(0xFFF5C419),),
  409. onTap: (){
  410. _postAgreementData(0);
  411. },
  412. ),
  413. Icon(Icons.share,size: 20,color: Color(0xFF404040),),
  414. ],
  415. ),
  416. ),
  417. ],
  418. ),
  419. ),
  420. );
  421. }
  422. _showInputView({int type,int toUserid,int fatherCommentId,int fromUserId}){
  423. TextEditingController _text = TextEditingController();
  424. Navigator.push(context, PopRoute(child: BottomInputDialog(
  425. height: 140,
  426. inputView: Column(
  427. children: [
  428. Row(
  429. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  430. children: [
  431. Text('评论',style: TextStyle(fontSize: 15,color: Color(0xFF424242),decoration: TextDecoration.none,fontWeight: FontWeight.bold),),
  432. GestureDetector(
  433. child: Text('发布',style: TextStyle(fontSize: 15,color: Color(0xFF4187D9),decoration: TextDecoration.none,fontWeight: FontWeight.bold),),
  434. onTap: (){
  435. if(type==0){
  436. _postCommentData({'comment':_text.text,'topicId':widget.squareId,'fatherCommentId':0,'fromUserId':0});
  437. }else{
  438. _postCommentData({'comment':_text.text,'topicId':widget.squareId,'fatherCommentId':fatherCommentId,'toUserId':toUserid,'fromUserId':fromUserId});
  439. }
  440. },
  441. ),
  442. ],
  443. ),
  444. Container(
  445. height: 50,
  446. decoration: BoxDecoration(
  447. color: Color(0xFFF7F7F7),
  448. borderRadius: BorderRadius.all(Radius.circular(10))
  449. ),
  450. margin: EdgeInsets.only(top: 10,bottom: 10),
  451. child: CupertinoTextField(
  452. placeholder: '友善发言,理性讨论,阳光你我',
  453. style: TextStyle(fontSize: 14,color: Color(0xFF999999),decoration: TextDecoration.none,fontWeight: FontWeight.normal),
  454. placeholderStyle: TextStyle(fontSize: 14,color: Color(0xFF999999),decoration: TextDecoration.none,fontWeight: FontWeight.normal),
  455. decoration: BoxDecoration(),
  456. maxLines: 50,
  457. autofocus: true,
  458. controller: _text,
  459. ),
  460. ),
  461. Row(
  462. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  463. children: [
  464. Container(),
  465. Icon(Icons.tag_faces,size: 25,color: Color(0xFF5C5C5C),),
  466. ],
  467. )
  468. ],
  469. ),
  470. )));
  471. }
  472. _postCommentData(Map parma) async{
  473. Map dict = await ysRequestHttp(context,type: requestType.post,api: '/app/piazza/SquareCommunity/comment/add',parameter: parma,isLoading: false,isToken: true);
  474. if(dict!=null){
  475. _getSquareDetailData();
  476. }
  477. }
  478. Future<void> _getSquareDetailData() async{
  479. Map dict = await ysRequestHttp(context,type: requestType.get,api: '/app/piazza/SquareCommunity/details',parameter: {'id':widget.squareId,'type':widget.typeId},isLoading: true,isToken: true,refresh: (){
  480. _getSquareDetailData();
  481. });
  482. if(dict!=null){
  483. setState(() {
  484. _dict = dict['data'];
  485. });
  486. _refreshData();
  487. }
  488. }
  489. Future<void> _refreshData() async{
  490. _page = 1;
  491. Map dict = await ysRequestHttp(context,type: requestType.get,api: '/app/piazza/SquareCommunity/comment/list',parameter: {'pageNo':_page,'pageSize':10,'id':widget.squareId,'type':widget.typeId},isToken: true);
  492. if(dict!=null){
  493. setState(() {
  494. _dataArray = dict['data']['resultList'];
  495. _page = dict['data']['pageNum'];
  496. });
  497. }
  498. }
  499. Future<void> _loadMore() async{
  500. _page++;
  501. Map dict = await ysRequestHttp(context,type: requestType.get,api: '/app/piazza/SquareCommunity/comment/list',parameter: {'pageNo':_page,'pageSize':10,'id':widget.squareId,'type':widget.typeId},isToken: true);
  502. if(dict!=null){
  503. setState(() {
  504. _dataArray.addAll(dict['data']['resultList']);
  505. _page = dict['data']['pageNum'];
  506. });
  507. }
  508. }
  509. _postAgreementData(int type) async{
  510. Map request = {'type':type};
  511. request['topicId'] = widget.squareId;
  512. Map dict = await ysRequestHttp(context,type: requestType.post,api: '/app/piazza/SquareCommunity/likeAndCollect',parameter: request,isLoading: false,isToken: true,refresh: (){
  513. });
  514. if(dict!=null){
  515. setState(() {
  516. if(type==1){
  517. _dict['likeStatus'] = dict['data'];
  518. }else{
  519. _dict['collectStatus'] = dict['data'];
  520. }
  521. });
  522. }
  523. }
  524. }