home_page.dart 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. import 'package:cpt_main/modules/home/home_state.dart';
  2. import 'package:cs_resources/generated/assets.dart';
  3. import 'package:cs_resources/generated/l10n.dart';
  4. import 'package:cs_resources/theme/app_colors_theme.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter/src/widgets/framework.dart';
  7. import 'package:hooks_riverpod/hooks_riverpod.dart';
  8. import 'package:auto_route/auto_route.dart';
  9. import 'package:widgets/ext/ex_widget.dart';
  10. import 'package:widgets/my_appbar.dart';
  11. import 'package:widgets/my_load_image.dart';
  12. import 'package:widgets/my_text_view.dart';
  13. import 'item_home_category.dart';
  14. import 'home_view_model.dart';
  15. import 'item_home_last_news.dart';
  16. import 'item_home_last_trans.dart';
  17. import 'item_home_manage_guide.dart';
  18. import 'item_home_property_news.dart';
  19. @RoutePage()
  20. class HomePage extends HookConsumerWidget {
  21. const HomePage({super.key});
  22. @override
  23. Widget build(BuildContext context, WidgetRef ref) {
  24. final viewModel = ref.read(homeViewModelProvider.notifier);
  25. final state = ref.watch(homeViewModelProvider);
  26. return Scaffold(
  27. appBar: MyAppBar.appBar(context, "Good Afternoon,Mike",
  28. backgroundColor: context.appColors.whiteBG,
  29. actions: [
  30. Center(
  31. child: Stack(
  32. clipBehavior: Clip.none, // 不裁剪超出边界的内容
  33. alignment: Alignment.topLeft,
  34. children: <Widget>[
  35. // 通知图标
  36. const MyAssetImage(Assets.mainHomeNotificationIcon, width: 19, height: 20),
  37. //未读消息
  38. Positioned(
  39. left: 0,
  40. top: 0,
  41. child: Transform.translate(
  42. offset: const Offset(-10, -5),
  43. child: MyTextView(
  44. "99",
  45. boxWidth: 20.0,
  46. textColor: Colors.white,
  47. fontSize: 10,
  48. isFontLight: true,
  49. backgroundColor: context.appColors.redDefault,
  50. cornerRadius: 8,
  51. paddingTop: 2,
  52. paddingBottom: 2,
  53. textAlign: TextAlign.center,
  54. ),
  55. ),
  56. ),
  57. ],
  58. ).onTap(viewModel.gotoNotificationPage))
  59. .marginOnly(right: 15),
  60. ],
  61. showBottomDivider: true),
  62. backgroundColor: context.appColors.backgroundDefault,
  63. body: CustomScrollView(
  64. scrollDirection: Axis.vertical,
  65. physics: const BouncingScrollPhysics(),
  66. slivers: [
  67. //支付与奖励
  68. _buildPaymentAndRewardsWidget(context, ref),
  69. //间距
  70. _buildSliverSpace(20),
  71. //九宫选项组 (固定)
  72. _buildCategoryWidget(context, ref),
  73. //轮播图片 (动态)
  74. _buildBannerImage(),
  75. //最新的新闻(动态)
  76. _buildLastNews(context, ref),
  77. //最新的交易
  78. SliverToBoxAdapter(
  79. child: MyTextView(
  80. marginTop: 14,
  81. marginLeft: 15,
  82. marginBottom: 14,
  83. S.current.latest_transactions,
  84. textColor: context.appColors.textPrimary,
  85. fontSize: 16,
  86. isFontMedium: true,
  87. ),
  88. ),
  89. //最新交易列表 (动态)
  90. _buildLastTransaction(context, state),
  91. //房产新闻
  92. SliverToBoxAdapter(
  93. child: MyTextView(
  94. marginTop: 14,
  95. marginLeft: 15,
  96. marginBottom: 14,
  97. onClick: viewModel.gotoPropertyNewsPage,
  98. S.current.property_news,
  99. textColor: context.appColors.textPrimary,
  100. fontSize: 16,
  101. isFontMedium: true,
  102. ),
  103. ),
  104. //房产新闻列表 (动态)
  105. _buildPropertyNews(context, state),
  106. //管理员介绍 (固定)
  107. _buildManagementGuides(context, ref),
  108. //间距
  109. _buildSliverSpace(15),
  110. ],
  111. ),
  112. );
  113. }
  114. //顶部的支付与奖励的布局
  115. Widget _buildPaymentAndRewardsWidget(BuildContext context, WidgetRef ref) {
  116. final viewModel = ref.read(homeViewModelProvider.notifier);
  117. return SliverToBoxAdapter(
  118. child: Container(
  119. color: context.appColors.whiteBG,
  120. width: double.infinity,
  121. height: 45,
  122. child: Column(
  123. children: [
  124. Row(
  125. children: [
  126. Row(
  127. mainAxisSize: MainAxisSize.max,
  128. mainAxisAlignment: MainAxisAlignment.center,
  129. children: [
  130. const MyAssetImage(Assets.mainHomePaymentIcon, width: 16.5, height: 18).marginOnly(left: 20),
  131. MyTextView(
  132. S.current.payment,
  133. textColor: context.appColors.textBlack,
  134. fontSize: 15,
  135. isFontMedium: true,
  136. ).paddingOnly(left: 13, right: 13).expanded(),
  137. const MyAssetImage(Assets.mainHomeMoreIcon, width: 6, height: 8.5).marginOnly(right: 15),
  138. ],
  139. ).onTap(viewModel.gotoPaymentPage).expanded(),
  140. Container(color: context.appColors.dividerDefault, width: 0.5, height: double.infinity),
  141. Row(
  142. mainAxisSize: MainAxisSize.max,
  143. mainAxisAlignment: MainAxisAlignment.center,
  144. children: [
  145. const MyAssetImage(Assets.mainHomeRewardsIcon, width: 16.5, height: 17).marginOnly(left: 20),
  146. MyTextView(
  147. S.current.rewards,
  148. textColor: context.appColors.textBlack,
  149. fontSize: 15,
  150. isFontMedium: true,
  151. ).paddingOnly(left: 13, right: 4).expanded(),
  152. MyTextView(
  153. "9568",
  154. textColor: context.appColors.textBlack,
  155. fontSize: 15,
  156. isFontBold: true,
  157. ).paddingOnly(left: 1, right: 4),
  158. const MyAssetImage(Assets.mainHomeMoreIcon, width: 6, height: 8.5).marginOnly(right: 15),
  159. ],
  160. ).onTap(viewModel.gotoRewardsPage).expanded(),
  161. ],
  162. ).expanded(),
  163. //底部分割线
  164. Container(color: context.appColors.dividerDefault, height: 0.5, width: double.infinity),
  165. ],
  166. ),
  167. ),
  168. );
  169. }
  170. Widget _buildSliverSpace(double size) {
  171. return SliverToBoxAdapter(
  172. child: SizedBox(height: size),
  173. );
  174. }
  175. //九宫格选项组
  176. Widget _buildCategoryWidget(BuildContext context, WidgetRef ref) {
  177. final viewModel = ref.read(homeViewModelProvider.notifier);
  178. final state = ref.watch(homeViewModelProvider);
  179. return SliverGrid(
  180. gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
  181. crossAxisCount: 3, // 三列
  182. mainAxisSpacing: 10.0, // 主轴(上下)的间距
  183. crossAxisSpacing: 0.0, // 交叉轴(左右)的间距
  184. childAspectRatio: 9 / 8, // 子组件的宽高比
  185. ),
  186. delegate: SliverChildBuilderDelegate(
  187. (BuildContext context, int index) {
  188. return HomeCategoryItem(
  189. category: state.homeCategory[index],
  190. ).onTap(() {
  191. viewModel.switchCategory(index);
  192. }); // 生成每个网格项
  193. },
  194. childCount: state.homeCategory.length, // 总共的网格项数
  195. ),
  196. );
  197. }
  198. //Banner的布局
  199. Widget _buildBannerImage() {
  200. return SliverToBoxAdapter(
  201. child: Center(
  202. child: MyLoadImage(
  203. "https://t11.baidu.com/it/u=1326770860,192430039&fm=30&app=106&f=JPEG?w=640&h=427&s=33B5BFAA6A165BCA182937620300D077",
  204. width: 345,
  205. height: 152.5,
  206. cornerRadius: 5,
  207. ),
  208. ).marginOnly(top: 21),
  209. );
  210. }
  211. //最新新闻
  212. Widget _buildLastNews(BuildContext context, WidgetRef ref) {
  213. final viewModel = ref.read(homeViewModelProvider.notifier);
  214. final state = ref.watch(homeViewModelProvider);
  215. return SliverToBoxAdapter(
  216. child: Column(
  217. crossAxisAlignment: CrossAxisAlignment.start,
  218. mainAxisAlignment: MainAxisAlignment.start,
  219. children: [
  220. MyTextView(
  221. S.current.latest_news,
  222. fontSize: 16,
  223. marginTop: 14,
  224. marginBottom: 14,
  225. isFontMedium: true,
  226. onClick: viewModel.gotoLastNewsPage,
  227. textColor: context.appColors.textPrimary,
  228. ),
  229. SingleChildScrollView(
  230. scrollDirection: Axis.horizontal,
  231. physics: const BouncingScrollPhysics(),
  232. clipBehavior: Clip.none,
  233. child: Row(
  234. children: List.generate(state.lastNews.length, (index) {
  235. return LastNewsItem(
  236. lastNews: state.lastNews[index],
  237. );
  238. }),
  239. ),
  240. )
  241. ],
  242. ).paddingOnly(left: 15, right: 15));
  243. }
  244. //最新的交易列表
  245. Widget _buildLastTransaction(BuildContext context, HomeState state) {
  246. return SliverPadding(
  247. padding: const EdgeInsets.symmetric(horizontal: 15),
  248. sliver: DecoratedSliver(
  249. decoration: BoxDecoration(
  250. color: context.appColors.whiteBG,
  251. borderRadius: BorderRadius.circular(5.0),
  252. boxShadow: [
  253. BoxShadow(
  254. color: const Color(0xFF656565).withOpacity(0.1),
  255. offset: const Offset(0, 1.5),
  256. blurRadius: 2.5,
  257. spreadRadius: 1.5,
  258. ),
  259. ],
  260. ),
  261. sliver: SliverPadding(
  262. padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
  263. sliver: SliverList(
  264. delegate: SliverChildBuilderDelegate(
  265. (BuildContext context, int index) {
  266. return Padding(
  267. padding: const EdgeInsets.symmetric(vertical: 10),
  268. child: LastTransItem(
  269. lastTrans: state.lastTrans[index],
  270. ),
  271. );
  272. },
  273. childCount: state.lastTrans.length,
  274. ),
  275. ),
  276. ),
  277. ),
  278. );
  279. }
  280. //房产新闻的双列表
  281. Widget _buildPropertyNews(BuildContext context, HomeState state) {
  282. return SliverList(
  283. delegate: SliverChildListDelegate(
  284. [
  285. // PropertyNews(),
  286. // 第一个水平滑动列表
  287. _buildPropertyNewsHorizontalList(),
  288. const SizedBox(height: 10),
  289. // // 第二个水平滑动列表
  290. _buildPropertyNewsHorizontalList(),
  291. ],
  292. ),
  293. );
  294. }
  295. Widget _buildPropertyNewsHorizontalList() {
  296. return SingleChildScrollView(
  297. scrollDirection: Axis.horizontal,
  298. physics: const BouncingScrollPhysics(),
  299. clipBehavior: Clip.none,
  300. child: Row(
  301. children: List.generate(5, (index) {
  302. return PropertyNews();
  303. }),
  304. ).marginOnly(left: 15, right: 15),
  305. );
  306. }
  307. //管理员介绍
  308. Widget _buildManagementGuides(BuildContext context, WidgetRef ref) {
  309. final viewModel = ref.read(homeViewModelProvider.notifier);
  310. final state = ref.watch(homeViewModelProvider);
  311. return SliverToBoxAdapter(
  312. child: Column(
  313. crossAxisAlignment: CrossAxisAlignment.start,
  314. mainAxisAlignment: MainAxisAlignment.start,
  315. children: [
  316. MyTextView(
  317. S.current.strata_management_guides,
  318. fontSize: 16,
  319. marginTop: 14,
  320. marginBottom: 14,
  321. onClick: viewModel.gotoManageGuidePage,
  322. isFontMedium: true,
  323. textColor: context.appColors.textPrimary,
  324. ),
  325. SingleChildScrollView(
  326. scrollDirection: Axis.horizontal,
  327. physics: const BouncingScrollPhysics(),
  328. clipBehavior: Clip.none,
  329. child: Row(
  330. children: List.generate(state.manage_guide.length, (index) {
  331. return ManageGuideItem(
  332. manageGuide: state.manage_guide[index],
  333. );
  334. }),
  335. ),
  336. )
  337. ],
  338. ).paddingOnly(left: 15, right: 15));
  339. }
  340. }