home_page.dart 18 KB

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