video_search_page.dart 6.9 KB

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