home_page.dart 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. import 'dart:convert';
  2. import 'package:bbyyy/beans/tourist_goods_bean_entity.dart';
  3. import 'package:bbyyy/beans/tourist_public_shop_bean_entity.dart';
  4. import 'package:bbyyy/https/MyDio.dart';
  5. import 'package:bbyyy/https/url.dart';
  6. import 'package:bbyyy/my_tools/event_bus.dart';
  7. import 'package:bbyyy/my_tools/my_colors.dart';
  8. import 'package:bbyyy/my_tools/my_tools.dart';
  9. import 'package:bbyyy/my_tools/my_views.dart';
  10. import 'package:bbyyy/paegs/root_page/root_page_view.dart';
  11. import 'package:flutter/cupertino.dart';
  12. import 'package:flutter/material.dart';
  13. import 'package:flutter_svg/flutter_svg.dart';
  14. import 'package:flutter_swiper/flutter_swiper.dart';
  15. import 'package:pull_to_refresh/pull_to_refresh.dart';
  16. class HomePage1 extends StatefulWidget {
  17. @override
  18. _HomePage1State createState() => _HomePage1State();
  19. }
  20. class _HomePage1State extends State<HomePage1>
  21. with AutomaticKeepAliveClientMixin {
  22. var imgs = ['images/banner1.png', 'images/banner2.png', 'images/banner3.png'];
  23. int selectedIndex = 0;
  24. var tabs = ['全部'];
  25. var types = ['货帮', '货品'];
  26. List<DropdownMenuItem<String>> sortItems = [];
  27. int typeIndex = 1;
  28. ScrollController _controller = ScrollController();
  29. double maxH;
  30. double minH = 164;
  31. double H = 0;
  32. bool showInput = false;
  33. TextEditingController _description = TextEditingController();
  34. FocusNode _descriptionFocus = FocusNode();
  35. RefreshController _reController = RefreshController(initialRefresh: true);
  36. int page = 1;
  37. int pageIndex = 0;
  38. List<TouristPublicShopBeanData> shops = [];
  39. List<TouristGoodsBeanData> goods = [];
  40. @override
  41. void initState() {
  42. super.initState();
  43. EventBus().on('toTop', (arg) {
  44. _controller.animateTo(0.0,
  45. duration: Duration(milliseconds: 200), curve: Curves.easeIn);
  46. });
  47. _controller.addListener(() {
  48. setState(() {
  49. if (_controller.offset == 0) {
  50. RootPageView().toTop = false;
  51. EventBus().emit('ChangePage');
  52. } else {
  53. RootPageView().toTop = true;
  54. EventBus().emit('ChangePage');
  55. }
  56. H = maxH - _controller.offset;
  57. if (H < minH) {
  58. H = minH;
  59. } else if (H > maxH) {
  60. H = maxH;
  61. }
  62. });
  63. });
  64. _descriptionFocus.addListener(() {
  65. if (_descriptionFocus.hasFocus) {
  66. } else {
  67. if (_description.text.isEmpty) {
  68. showInput = false;
  69. }
  70. }
  71. });
  72. }
  73. @override
  74. void dispose() {
  75. // TODO: implement dispose
  76. super.dispose();
  77. EventBus().off('commodity_category');
  78. EventBus().off('uploadGoods');
  79. EventBus().off('toTop');
  80. }
  81. @override
  82. Widget build(BuildContext context) {
  83. maxH = MediaQuery.of(context).size.width * (520 / 750);
  84. minH = MediaQuery.of(context).padding.top + 64;
  85. if (H == 0) {
  86. H = maxH;
  87. }
  88. return GestureDetector(
  89. onTap: () {
  90. MyTools().hideKeyboard(context);
  91. },
  92. behavior: HitTestBehavior.translucent,
  93. child: Scaffold(
  94. body: Column(
  95. children: [
  96. Stack(
  97. children: [
  98. AnimatedContainer(
  99. height: H,
  100. duration: Duration(milliseconds: 200),
  101. child: Swiper(
  102. itemBuilder: (BuildContext context, int index) {
  103. return new Image.asset(
  104. "${imgs[index]}",
  105. fit: BoxFit.cover,
  106. );
  107. },
  108. itemCount: 3,
  109. viewportFraction: 1,
  110. scale: 1,
  111. autoplay: true,
  112. ),
  113. ),
  114. SafeArea(
  115. bottom: false,
  116. child: Container(
  117. margin: EdgeInsets.only(top: 18),
  118. width: double.infinity,
  119. child: Row(
  120. children: [
  121. GestureDetector(
  122. onTap: () {
  123. setState(() {
  124. pageIndex = 0;
  125. _reController.requestRefresh();
  126. });
  127. },
  128. behavior: HitTestBehavior.translucent,
  129. child: Container(
  130. height: 28,
  131. width: 60,
  132. alignment: Alignment.center,
  133. child: Column(
  134. children: [
  135. Text(
  136. '货帮',
  137. style: TextStyle(
  138. color: pageIndex == 0
  139. ? MyColors.cFF4233
  140. : MyColors.c333333,
  141. fontSize: 16,
  142. fontWeight: FontWeight.bold),
  143. ),
  144. Visibility(
  145. child: Container(
  146. width: 32,
  147. height: 2,
  148. decoration: BoxDecoration(
  149. color: MyColors.cFF4233,
  150. borderRadius: BorderRadius.circular(1)),
  151. ),
  152. visible: pageIndex == 0,
  153. ),
  154. ],
  155. ),
  156. ),
  157. ),
  158. Container(
  159. width: 40,
  160. ),
  161. GestureDetector(
  162. onTap: () {
  163. setState(() {
  164. pageIndex = 1;
  165. _reController.requestRefresh();
  166. });
  167. },
  168. behavior: HitTestBehavior.translucent,
  169. child: Container(
  170. height: 28,
  171. width: 60,
  172. alignment: Alignment.center,
  173. child: Column(
  174. children: [
  175. Text(
  176. '商品',
  177. style: TextStyle(
  178. color: pageIndex == 1
  179. ? MyColors.cFF4233
  180. : MyColors.c333333,
  181. fontSize: 16,
  182. fontWeight: FontWeight.bold),
  183. ),
  184. Visibility(
  185. child: Container(
  186. width: 32,
  187. height: 2,
  188. decoration: BoxDecoration(
  189. color: MyColors.cFF4233,
  190. borderRadius: BorderRadius.circular(1)),
  191. ),
  192. visible: pageIndex == 1,
  193. ),
  194. ],
  195. ),
  196. ),
  197. ),
  198. ],
  199. mainAxisAlignment: MainAxisAlignment.center,
  200. ),
  201. ),
  202. ),
  203. SafeArea(
  204. bottom: false,
  205. child: Container(
  206. margin: EdgeInsets.only(top: 18),
  207. width: double.infinity,
  208. child: GestureDetector(
  209. onTap: (){
  210. EventBus().emit('toLogin');
  211. },
  212. child: Container(
  213. decoration: BoxDecoration(
  214. color: MyColors.cFF4233,
  215. borderRadius: BorderRadius.circular(14)),
  216. height: 28,
  217. width: 28,
  218. child: SvgPicture.asset(
  219. 'images/svg/搜索.svg',
  220. height: 15,
  221. width: 15,
  222. color: Colors.white,
  223. ),
  224. alignment: Alignment.center,
  225. margin: EdgeInsets.only(right: 15),
  226. ),
  227. ),
  228. alignment: Alignment.centerRight,
  229. ),
  230. ),
  231. ],
  232. ),
  233. Expanded(
  234. flex: 1,
  235. child: SmartRefresher(
  236. controller: _reController,
  237. onRefresh: onRefresh,
  238. onLoading: onLoading,
  239. enablePullDown: true,
  240. enablePullUp: true,
  241. child: body(),
  242. ),
  243. )
  244. ],
  245. ),
  246. ),
  247. );
  248. }
  249. @override
  250. // TODO: implement wantKeepAlive
  251. bool get wantKeepAlive => true;
  252. void onRefresh() {
  253. page = 1;
  254. touristQueryData();
  255. }
  256. void onLoading() {
  257. page++;
  258. touristQueryData();
  259. }
  260. body() {
  261. if (pageIndex == 1) {
  262. return body1();
  263. } else if (pageIndex == 0) {
  264. return body2();
  265. }
  266. }
  267. body1() {
  268. double w = (MediaQuery.of(context).size.width - 28 - 8) / 2;
  269. if (goods.length == 0) {
  270. return SingleChildScrollView(child: noData());
  271. } else {
  272. return GridView.builder(
  273. controller: _controller,
  274. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  275. crossAxisCount: 2,
  276. childAspectRatio: 164 / 261,
  277. mainAxisSpacing: 8,
  278. crossAxisSpacing: 8),
  279. itemCount: goods.length,
  280. padding: EdgeInsets.only(left: 14, right: 14, top: 14, bottom: 65),
  281. itemBuilder: (context, index) {
  282. return GestureDetector(
  283. onTap: () {
  284. EventBus().emit('toLogin');
  285. },
  286. behavior: HitTestBehavior.translucent,
  287. child: Card(
  288. elevation: 2,
  289. shadowColor: MyColors.c21333333,
  290. child: Column(
  291. children: [
  292. Padding(
  293. padding: EdgeInsets.only(left: 6, top: 6, bottom: 3),
  294. child: Row(
  295. children: [
  296. ClipRRect(
  297. child: MyViews()
  298. .netImg(imgURL(goods[index].shopPic), 20, 20),
  299. borderRadius: BorderRadius.all(Radius.circular(10)),
  300. ),
  301. Expanded(
  302. child: Container(
  303. margin: EdgeInsets.only(right: 5, left: 5),
  304. child: Text(
  305. goods[index].shopName,
  306. style: TextStyle(
  307. color: MyColors.c999999,
  308. fontSize: 10,
  309. ),
  310. maxLines: 1,
  311. overflow: TextOverflow.ellipsis,
  312. softWrap: true,
  313. ),
  314. ),
  315. ),
  316. ],
  317. ),
  318. ),
  319. MyViews().netImg(imgURL(goods[index].coverPath), w, w,
  320. placeholder: 'images/svg/goodsDefImg.svg'),
  321. Container(
  322. padding: EdgeInsets.only(right: 6, left: 6, top: 8),
  323. child: Text(
  324. '${goods[index].title}\n${goods[index].description}',
  325. style: TextStyle(color: Colors.black, fontSize: 12),
  326. maxLines: 1,
  327. overflow: TextOverflow.ellipsis,
  328. softWrap: true,
  329. ),
  330. ),
  331. Container(
  332. padding: EdgeInsets.only(right: 6, left: 6, top: 7),
  333. child: Row(
  334. children: [
  335. Expanded(
  336. child: Text(
  337. '¥${goods[index].price}',
  338. style: TextStyle(
  339. color: MyColors.cFF4233, fontSize: 15),
  340. ),
  341. ),
  342. Container(
  343. child: Text(
  344. '详情',
  345. style: TextStyle(
  346. color: MyColors.cFF4233, fontSize: 12),
  347. ),
  348. alignment: Alignment.center,
  349. padding: EdgeInsets.only(bottom: 2),
  350. decoration: BoxDecoration(
  351. border: Border.all(
  352. color: MyColors.cFF4233, width: 1),
  353. borderRadius:
  354. BorderRadius.all(Radius.circular(10))),
  355. height: 20,
  356. width: 50,
  357. )
  358. ],
  359. ),
  360. )
  361. ],
  362. crossAxisAlignment: CrossAxisAlignment.start,
  363. ),
  364. ),
  365. );
  366. });
  367. }
  368. }
  369. body2() {
  370. if (shops.length == 0) {
  371. return SingleChildScrollView(child: noData());
  372. } else {
  373. return ListView.builder(
  374. controller: _controller,
  375. itemBuilder: (BuildContext context, int index) {
  376. return GestureDetector(
  377. onTap: () {
  378. EventBus().emit('toLogin');
  379. },
  380. behavior: HitTestBehavior.translucent,
  381. child: Container(
  382. margin: EdgeInsets.only(bottom: 5),
  383. child: Card(
  384. elevation: 2,
  385. child: Padding(
  386. padding: const EdgeInsets.all(10),
  387. child: Row(
  388. children: [
  389. ClipRRect(
  390. child: MyViews().netImg(
  391. imgURL(shops[index].picture), 70, 70,
  392. placeholder: 'images/svg/goodsDefImg.svg'),
  393. borderRadius: BorderRadius.circular(4),
  394. ),
  395. Expanded(
  396. child: Container(
  397. height: 70,
  398. margin: EdgeInsets.only(left: 10),
  399. child: Column(
  400. children: [
  401. MyViews().myText(
  402. '${shops[index].name}(${shops[index].uid})',
  403. MyColors.c333333,
  404. 14),
  405. Text(
  406. '货帮介绍:${shops[index].introduction}',
  407. style: TextStyle(
  408. color: MyColors.c666666, fontSize: 11),
  409. maxLines: 1,
  410. overflow: TextOverflow.ellipsis,
  411. softWrap: true,
  412. ),
  413. Row(
  414. children: [
  415. Icon(
  416. Icons.location_on_outlined,
  417. size: 15,
  418. color: MyColors.c666666,
  419. ),
  420. Expanded(
  421. child: Text(
  422. '${shops[index].address}',
  423. style: TextStyle(
  424. color: MyColors.c666666,
  425. fontSize: 10),
  426. maxLines: 1,
  427. overflow: TextOverflow.ellipsis,
  428. softWrap: true,
  429. ),
  430. ),
  431. ],
  432. ),
  433. ],
  434. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  435. crossAxisAlignment: CrossAxisAlignment.start,
  436. ),
  437. ),
  438. )
  439. ],
  440. ),
  441. ),
  442. ),
  443. ),
  444. );
  445. },
  446. itemCount: shops.length,
  447. padding: EdgeInsets.all(16),
  448. );
  449. }
  450. }
  451. void touristQueryData() {
  452. MyDio().post('/model/visitHome', {'type': pageIndex, 'page': page},
  453. (response, hasError) {
  454. if (!hasError) {
  455. if (pageIndex == 0) {
  456. TouristPublicShopBeanEntity entity = TouristPublicShopBeanEntity()
  457. .fromJson(json.decode(response.data.toString()));
  458. if (page == 1) {
  459. shops.clear();
  460. }
  461. shops.addAll(entity.data);
  462. } else {
  463. TouristGoodsBeanEntity entity = TouristGoodsBeanEntity()
  464. .fromJson(json.decode(response.data.toString()));
  465. if (page == 1) {
  466. goods.clear();
  467. }
  468. goods.addAll(entity.data);
  469. }
  470. setState(() {});
  471. }
  472. endRe(_reController);
  473. }, (error) {});
  474. }
  475. }