home_page.dart 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  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. child: Container(
  116. margin: EdgeInsets.only(top: 18),
  117. width: double.infinity,
  118. child: Row(
  119. children: [
  120. GestureDetector(
  121. onTap: () {
  122. setState(() {
  123. pageIndex = 0;
  124. _reController.requestRefresh();
  125. });
  126. },
  127. behavior: HitTestBehavior.translucent,
  128. child: Container(
  129. height: 28,
  130. width: 60,
  131. alignment: Alignment.center,
  132. child: Column(
  133. children: [
  134. Text(
  135. '店铺',
  136. style: TextStyle(
  137. color: pageIndex == 0
  138. ? MyColors.cFF4233
  139. : MyColors.c333333,
  140. fontSize: 16,
  141. fontWeight: FontWeight.bold),
  142. ),
  143. Visibility(
  144. child: Container(
  145. width: 32,
  146. height: 2,
  147. decoration: BoxDecoration(
  148. color: MyColors.cFF4233,
  149. borderRadius: BorderRadius.circular(1)),
  150. ),
  151. visible: pageIndex == 0,
  152. ),
  153. ],
  154. ),
  155. ),
  156. ),
  157. Container(
  158. width: 40,
  159. ),
  160. GestureDetector(
  161. onTap: () {
  162. setState(() {
  163. pageIndex = 1;
  164. _reController.requestRefresh();
  165. });
  166. },
  167. behavior: HitTestBehavior.translucent,
  168. child: Container(
  169. height: 28,
  170. width: 60,
  171. alignment: Alignment.center,
  172. child: Column(
  173. children: [
  174. Text(
  175. '商品',
  176. style: TextStyle(
  177. color: pageIndex == 1
  178. ? MyColors.cFF4233
  179. : MyColors.c333333,
  180. fontSize: 16,
  181. fontWeight: FontWeight.bold),
  182. ),
  183. Visibility(
  184. child: Container(
  185. width: 32,
  186. height: 2,
  187. decoration: BoxDecoration(
  188. color: MyColors.cFF4233,
  189. borderRadius: BorderRadius.circular(1)),
  190. ),
  191. visible: pageIndex == 1,
  192. ),
  193. ],
  194. ),
  195. ),
  196. ),
  197. ],
  198. mainAxisAlignment: MainAxisAlignment.center,
  199. ),
  200. ),
  201. ),
  202. SafeArea(
  203. child: Container(
  204. margin: EdgeInsets.only(top: 18),
  205. width: double.infinity,
  206. child: GestureDetector(
  207. onTap: (){
  208. EventBus().emit('toLogin');
  209. },
  210. child: Container(
  211. decoration: BoxDecoration(
  212. color: MyColors.cFF4233,
  213. borderRadius: BorderRadius.circular(14)),
  214. height: 28,
  215. width: 28,
  216. child: SvgPicture.asset(
  217. 'images/svg/搜索.svg',
  218. height: 15,
  219. width: 15,
  220. color: Colors.white,
  221. ),
  222. alignment: Alignment.center,
  223. margin: EdgeInsets.only(right: 15),
  224. ),
  225. ),
  226. alignment: Alignment.centerRight,
  227. ),
  228. ),
  229. ],
  230. ),
  231. Expanded(
  232. flex: 1,
  233. child: SmartRefresher(
  234. controller: _reController,
  235. onRefresh: onRefresh,
  236. onLoading: onLoading,
  237. enablePullDown: true,
  238. enablePullUp: true,
  239. child: body(),
  240. ),
  241. )
  242. ],
  243. ),
  244. ),
  245. );
  246. }
  247. @override
  248. // TODO: implement wantKeepAlive
  249. bool get wantKeepAlive => true;
  250. void onRefresh() {
  251. page = 1;
  252. touristQueryData();
  253. }
  254. void onLoading() {
  255. page++;
  256. touristQueryData();
  257. }
  258. body() {
  259. if (pageIndex == 1) {
  260. return body1();
  261. } else if (pageIndex == 0) {
  262. return body2();
  263. }
  264. }
  265. body1() {
  266. double w = (MediaQuery.of(context).size.width - 28 - 8) / 2;
  267. if (goods.length == 0) {
  268. return noData();
  269. } else {
  270. return GridView.builder(
  271. controller: _controller,
  272. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  273. crossAxisCount: 2,
  274. childAspectRatio: 164 / 261,
  275. mainAxisSpacing: 8,
  276. crossAxisSpacing: 8),
  277. itemCount: goods.length,
  278. padding: EdgeInsets.only(left: 14, right: 14, top: 14, bottom: 65),
  279. itemBuilder: (context, index) {
  280. return GestureDetector(
  281. onTap: () {
  282. EventBus().emit('toLogin');
  283. },
  284. behavior: HitTestBehavior.translucent,
  285. child: Card(
  286. elevation: 2,
  287. shadowColor: MyColors.c21333333,
  288. child: Column(
  289. children: [
  290. Padding(
  291. padding: EdgeInsets.only(left: 6, top: 6, bottom: 3),
  292. child: Row(
  293. children: [
  294. ClipRRect(
  295. child: MyViews()
  296. .netImg(imgURL(goods[index].shopPic), 20, 20),
  297. borderRadius: BorderRadius.all(Radius.circular(10)),
  298. ),
  299. Expanded(
  300. child: Container(
  301. margin: EdgeInsets.only(right: 5, left: 5),
  302. child: Text(
  303. goods[index].shopName,
  304. style: TextStyle(
  305. color: MyColors.c999999,
  306. fontSize: 10,
  307. ),
  308. maxLines: 1,
  309. overflow: TextOverflow.ellipsis,
  310. softWrap: true,
  311. ),
  312. ),
  313. ),
  314. ],
  315. ),
  316. ),
  317. MyViews().netImg(imgURL(goods[index].coverPath), w, w,
  318. placeholder: 'images/svg/goodsDefImg.svg'),
  319. Container(
  320. padding: EdgeInsets.only(right: 6, left: 6, top: 8),
  321. child: Text(
  322. '${goods[index].title}\n${goods[index].description}',
  323. style: TextStyle(color: Colors.black, fontSize: 12),
  324. maxLines: 1,
  325. overflow: TextOverflow.ellipsis,
  326. softWrap: true,
  327. ),
  328. ),
  329. Container(
  330. padding: EdgeInsets.only(right: 6, left: 6, top: 7),
  331. child: Row(
  332. children: [
  333. Expanded(
  334. child: Text(
  335. '¥${goods[index].price}',
  336. style: TextStyle(
  337. color: MyColors.cFF4233, fontSize: 15),
  338. ),
  339. ),
  340. Container(
  341. child: Text(
  342. '详情',
  343. style: TextStyle(
  344. color: MyColors.cFF4233, fontSize: 12),
  345. ),
  346. alignment: Alignment.center,
  347. padding: EdgeInsets.only(bottom: 2),
  348. decoration: BoxDecoration(
  349. border: Border.all(
  350. color: MyColors.cFF4233, width: 1),
  351. borderRadius:
  352. BorderRadius.all(Radius.circular(10))),
  353. height: 20,
  354. width: 50,
  355. )
  356. ],
  357. ),
  358. )
  359. ],
  360. crossAxisAlignment: CrossAxisAlignment.start,
  361. ),
  362. ),
  363. );
  364. });
  365. }
  366. }
  367. body2() {
  368. if (shops.length == 0) {
  369. return noData();
  370. } else {
  371. return ListView.builder(
  372. controller: _controller,
  373. itemBuilder: (BuildContext context, int index) {
  374. return GestureDetector(
  375. onTap: () {
  376. EventBus().emit('toLogin');
  377. },
  378. behavior: HitTestBehavior.translucent,
  379. child: Container(
  380. margin: EdgeInsets.only(bottom: 5),
  381. child: Card(
  382. elevation: 2,
  383. child: Padding(
  384. padding: const EdgeInsets.all(10),
  385. child: Row(
  386. children: [
  387. ClipRRect(
  388. child: MyViews().netImg(
  389. imgURL(shops[index].picture), 70, 70,
  390. placeholder: 'images/svg/goodsDefImg.svg'),
  391. borderRadius: BorderRadius.circular(4),
  392. ),
  393. Expanded(
  394. child: Container(
  395. height: 70,
  396. margin: EdgeInsets.only(left: 10),
  397. child: Column(
  398. children: [
  399. MyViews().myText(
  400. '${shops[index].name}(${shops[index].uid})',
  401. MyColors.c333333,
  402. 14),
  403. Text(
  404. '店铺介绍:${shops[index].introduction}',
  405. style: TextStyle(
  406. color: MyColors.c666666, fontSize: 11),
  407. maxLines: 1,
  408. overflow: TextOverflow.ellipsis,
  409. softWrap: true,
  410. ),
  411. Row(
  412. children: [
  413. Icon(
  414. Icons.location_on_outlined,
  415. size: 15,
  416. color: MyColors.c666666,
  417. ),
  418. Expanded(
  419. child: Text(
  420. '${shops[index].address}',
  421. style: TextStyle(
  422. color: MyColors.c666666,
  423. fontSize: 10),
  424. maxLines: 1,
  425. overflow: TextOverflow.ellipsis,
  426. softWrap: true,
  427. ),
  428. ),
  429. ],
  430. ),
  431. ],
  432. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  433. crossAxisAlignment: CrossAxisAlignment.start,
  434. ),
  435. ),
  436. )
  437. ],
  438. ),
  439. ),
  440. ),
  441. ),
  442. );
  443. },
  444. itemCount: shops.length,
  445. padding: EdgeInsets.all(16),
  446. );
  447. }
  448. }
  449. void touristQueryData() {
  450. MyDio().post('/model/visitHome', {'type': pageIndex, 'page': page},
  451. (response, hasError) {
  452. if (!hasError) {
  453. if (pageIndex == 0) {
  454. TouristPublicShopBeanEntity entity = TouristPublicShopBeanEntity()
  455. .fromJson(json.decode(response.data.toString()));
  456. if (page == 1) {
  457. shops.clear();
  458. }
  459. shops.addAll(entity.data);
  460. } else {
  461. TouristGoodsBeanEntity entity = TouristGoodsBeanEntity()
  462. .fromJson(json.decode(response.data.toString()));
  463. if (page == 1) {
  464. goods.clear();
  465. }
  466. goods.addAll(entity.data);
  467. }
  468. setState(() {});
  469. }
  470. endRe(_reController);
  471. }, (error) {});
  472. }
  473. }