home_page.dart 12 KB

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