search_result_page.dart 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import 'package:easy_refresh/easy_refresh.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_riverpod/flutter_riverpod.dart';
  4. import 'package:flutter_screenutil/flutter_screenutil.dart';
  5. import 'package:news_app/constant/color_res.dart';
  6. import 'package:news_app/constant/size_res.dart';
  7. import 'package:news_app/extension/base.dart';
  8. import 'package:news_app/provider/search_provider.dart';
  9. import 'package:news_app/ui/news/news_child_main_page.dart';
  10. import 'package:news_app/widget/load_image.dart';
  11. import '../../widget/my_txt.dart';
  12. /// @author: bo.zeng
  13. /// @email: cnhbwds@gmail.com
  14. /// @date: 2025 2025/4/25 13:18
  15. /// @description:
  16. final searchProvider = NotifierProvider<SearchProvider, SearchData>(
  17. () => SearchProvider(),
  18. );
  19. class SearchResultPage extends ConsumerStatefulWidget {
  20. const SearchResultPage({super.key});
  21. @override
  22. ConsumerState<SearchResultPage> createState() => _SearchResultPageState();
  23. }
  24. class _SearchResultPageState extends ConsumerState<SearchResultPage> {
  25. int pageNum = 0;
  26. String keyword = '';
  27. int total = 0;
  28. final TextEditingController _searchController = TextEditingController();
  29. @override
  30. void initState() {
  31. // TODO: implement initState
  32. super.initState();
  33. ref.read(searchProvider.notifier)
  34. .fetchArticleHotWord("article");
  35. }
  36. @override
  37. void dispose() {
  38. _searchController.dispose();
  39. // TODO: implement dispose
  40. super.dispose();
  41. }
  42. @override
  43. Widget build(BuildContext context) {
  44. final result = ref.watch(searchProvider);
  45. ref.listen(searchProvider, (pre, next) {
  46. total = next.searchModel?.rows?.length ?? 0;
  47. });
  48. return Scaffold(
  49. appBar: AppBar(
  50. scrolledUnderElevation: 0,
  51. title: SizedBox(
  52. height: 40.h,
  53. child: TextField(
  54. controller: _searchController,
  55. textInputAction: TextInputAction.search,
  56. decoration: InputDecoration(
  57. hintText: '输入您想搜索的内容',
  58. hintStyle: TextStyle(color: color001842, fontSize: 16),
  59. border: OutlineInputBorder(
  60. borderRadius: BorderRadius.circular(30.r),
  61. borderSide: BorderSide.none,
  62. ),
  63. filled: true,
  64. prefixIcon: Icon(Icons.search, color: color66748E),
  65. fillColor: colorF9F9F9,
  66. contentPadding: EdgeInsets.zero,
  67. ),
  68. style: TextStyle(color: color333333, fontSize: 16),
  69. cursorColor: color333333,
  70. onSubmitted: (value) {
  71. keyword = value;
  72. if (keyword.isNotEmpty) {
  73. ref.read(searchProvider.notifier).fetchSearch(keyword, 0);
  74. }
  75. },
  76. ),
  77. ),
  78. ),
  79. body: EasyRefresh.builder(
  80. onLoad: () async {
  81. if (total >= (result.searchModel?.total ?? 0).safeValue) {
  82. return IndicatorResult.noMore;
  83. } else {
  84. pageNum++;
  85. await ref
  86. .read(searchProvider.notifier)
  87. .fetchSearch(keyword, pageNum);
  88. return IndicatorResult.success;
  89. }
  90. },
  91. childBuilder: (context, py) {
  92. return CustomScrollView(
  93. physics:py,
  94. slivers: [
  95. SliverToBoxAdapter(
  96. child: Padding(
  97. padding: EdgeInsets.symmetric(
  98. horizontal: horizontalPadding,
  99. vertical: horizontalPadding+6.h,
  100. ),
  101. child: Row(
  102. crossAxisAlignment: CrossAxisAlignment.center,
  103. // mainAxisAlignment: MainAxisAlignment.center,
  104. children: [
  105. LoadAssetImage('search_hot',width: 12.w,height: 12.h,),
  106. SizedBox(width: 2.w,),
  107. myTxt(
  108. text: "热门搜索",
  109. color: Colors.black,
  110. fontWeight: FontWeight.bold,
  111. fontSize: 14.sp,
  112. ),
  113. ],
  114. ),
  115. ),
  116. ),
  117. SliverPadding(
  118. padding: EdgeInsets.symmetric(
  119. horizontal: horizontalPadding,
  120. ),
  121. sliver: SliverGrid.count(
  122. crossAxisCount: 2,
  123. mainAxisSpacing: 10.w,
  124. crossAxisSpacing: 10.w,
  125. childAspectRatio: 1 / 0.1,
  126. children: [
  127. ...List.generate(
  128. (result.hotWords).length,
  129. (index) {
  130. return GestureDetector(
  131. onTap: (){
  132. pageNum = 0;
  133. keyword = result.hotWords[index].word ?? '';
  134. _searchController.text = keyword;
  135. ref.read(searchProvider.notifier)
  136. .fetchSearch(keyword, pageNum);
  137. },
  138. child: myTxt(
  139. text: result.hotWords[index].word ?? '',
  140. color: Colors.black,
  141. fontWeight: FontWeight.normal,
  142. fontSize: 14.sp,
  143. ),
  144. );
  145. },
  146. ),
  147. ],
  148. ),
  149. ),
  150. SliverPadding(
  151. padding: EdgeInsets.all(horizontalPadding),
  152. sliver: SliverList.separated(
  153. separatorBuilder: (context, index) {
  154. return SizedBox(height: 10.h);
  155. },
  156. itemBuilder: (context, index) {
  157. return buildNewsNewItem(result.searchModel?.rows?[index], context);
  158. },
  159. itemCount: result.searchModel?.rows?.length ?? 0,
  160. ),
  161. ),
  162. ],
  163. );
  164. // ListView.separated(
  165. // padding: EdgeInsets.all(horizontalPadding),
  166. // separatorBuilder: (context, index) {
  167. // return Container(height: 10.h);
  168. // },
  169. // physics: py,
  170. // itemBuilder: (context, index) {
  171. // return buildNewsNewItem(result.rows?[index], context);
  172. // },
  173. // itemCount: result.rows?.length ?? 0,
  174. // );
  175. },
  176. ),
  177. );
  178. }
  179. }