基础组件库
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

search_tab_widget.dart 6.3 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. import 'dart:convert';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:cached_network_image/cached_network_image.dart';
  5. import 'package:tab_indicator_styler/tab_indicator_styler.dart';
  6. import 'package:zhiying_base_widget/pages/search_page/notifier/search_tag_notifier.dart';
  7. import 'package:zhiying_base_widget/pages/search_result_page/search_result_page.dart';
  8. import 'package:zhiying_base_widget/pages/search_think_page/bloc/search_think_bloc.dart';
  9. import 'package:zhiying_base_widget/pages/search_think_page/model/search_think_model.dart';
  10. import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart';
  11. import 'package:zhiying_base_widget/widgets/search/tabbar/search_tab_sk.dart';
  12. import 'package:zhiying_base_widget/widgets/search/widget/my_tab.dart';
  13. import 'package:flutter_bloc/flutter_bloc.dart';
  14. import 'package:zhiying_comm/zhiying_comm.dart';
  15. import 'package:provider/provider.dart';
  16. import 'model/search_tab_model.dart';
  17. class SearchTabWidget extends StatefulWidget {
  18. final Map<String, dynamic> data;
  19. SearchTabModel model;
  20. SearchTabWidget(this.data, {Key key}) : super(key: key) {
  21. try {
  22. model = SearchTabModel.fromJson(jsonDecode(data['data']));
  23. } catch (e) {
  24. Logger.error(e.toString());
  25. }
  26. }
  27. @override
  28. _SearchTabWidgetState createState() => _SearchTabWidgetState();
  29. }
  30. class _SearchTabWidgetState extends State<SearchTabWidget> {
  31. TabController _tabController;
  32. String _type = 'taobao';
  33. /// 联想列表的item点击事件
  34. _onThinkItemClick(SearchThinkModel model){
  35. model.type = _type;
  36. RouterUtil.hideKeyboard(context);
  37. Provider.of<SearchTagNotifier>(context, listen: false).addTag(model?.keywords);
  38. BlocProvider.of<SearchThinkBloc>(context).add(SearchThinkShowBaseViewEvent());
  39. Navigator.push(context, CupertinoPageRoute(
  40. builder: (_)=> SearchResultPage(model.toJson()..['tag'] = 'search_page')
  41. ));
  42. }
  43. @override
  44. void initState() {
  45. _tabController = TabController(length: widget?.model?.search_icon_list?.length ?? 0, vsync: ScrollableState())..addListener((){
  46. // String type = '';
  47. // try{
  48. // type = widget.model.search_icon_list[_tabController.index].type;
  49. // }catch(_){}
  50. // if(!EmptyUtil.isEmpty(type)) {
  51. // BlocProvider.of<SearchThinkBloc>(context).add(SearchThinkChangeTypeEvent(type));
  52. // }
  53. if(!_tabController.indexIsChanging){
  54. Logger.log('_tabController.indexIsChanging = ${_tabController?.index}');
  55. try{
  56. _type = widget.model.search_icon_list[_tabController.index].type;
  57. }catch(e, s){
  58. Logger.error(e,s);
  59. }
  60. }
  61. });
  62. super.initState();
  63. }
  64. @override
  65. void dispose() {
  66. _tabController?.dispose();
  67. super.dispose();
  68. }
  69. @override
  70. Widget build(BuildContext context) {
  71. return _getMainWidget(widget?.model);
  72. }
  73. /// 获取主视图
  74. Widget _getMainWidget(SearchTabModel model) {
  75. return Visibility(
  76. replacement: SearchTabSkeleton(),
  77. visible: !EmptyUtil.isEmpty(model),
  78. child: _getTabar(model),
  79. );
  80. }
  81. /// 获取TabBar
  82. Widget _getTabar(SearchTabModel model) {
  83. return Container(
  84. margin: const EdgeInsets.only(/*left: 12.5, right: 12.5,*/ top: 20),
  85. child: Column(
  86. children: <Widget>[
  87. TabBar(
  88. controller: _tabController,
  89. isScrollable: true,
  90. labelStyle: TextStyle( fontSize: 14, fontWeight: FontWeight.bold),
  91. unselectedLabelColor: HexColor.fromHex('#999999'),
  92. labelColor: HexColor.fromHex('#FF4242'),
  93. // indicatorSize: TabBarIndicatorSize.label,
  94. indicator: MaterialIndicator(
  95. height: 2.5,
  96. topLeftRadius: 8,
  97. topRightRadius: 8,
  98. bottomLeftRadius: 8,
  99. bottomRightRadius: 8,
  100. color: HexColor.fromHex('#FF4242'),
  101. horizontalPadding: 25,
  102. ),
  103. tabs: model.search_icon_list.map((item) {
  104. return MyTab(
  105. icon: CachedNetworkImage(imageUrl: item?.with_icon_color ?? '', width: 14,),
  106. text: item.name,
  107. );
  108. }).toList(),
  109. ),
  110. Expanded(
  111. child: _getItemWidget(model),
  112. ),
  113. ],
  114. ),
  115. );
  116. }
  117. /// 根据输入框,是否显示联想列表还是其它
  118. Widget _getItemWidget(SearchTabModel model){
  119. return Stack(
  120. children: <Widget>[
  121. _getTabBarView(model),
  122. BlocConsumer<SearchThinkBloc, SearchThinkState>(
  123. listener: (context, state){},
  124. buildWhen: (prev, current){
  125. if(current is SearchThinkErrorState){
  126. return false;
  127. }
  128. return true;
  129. },
  130. builder: (context, state){
  131. // return Visibility(
  132. // replacement: _getTabBarView(model),
  133. //
  134. // child: _getThinkListWidget(),
  135. // );
  136. if(state is SearchThinkLoadedState){
  137. return _getThinkListWidget(state.model);
  138. }
  139. return Container();
  140. },
  141. ),
  142. ],
  143. );
  144. }
  145. /// tabBarView
  146. Widget _getTabBarView(SearchTabModel model){
  147. return TabBarView(
  148. controller: _tabController,
  149. children: model.search_icon_list.map((item){
  150. // TODO 这里需要和后台沟通改成页面的唯一标示
  151. return PageFactory.create('search_item_page', item.toJson());
  152. }).toList(),
  153. );
  154. }
  155. /// 联想列表
  156. Widget _getThinkListWidget(List<SearchThinkModel> model){
  157. return Container(
  158. color: Colors.white,
  159. height: double.infinity,
  160. child: ListView.builder(itemBuilder: (context, index){
  161. SearchThinkModel item = model[index];
  162. return GestureDetector(
  163. onTap: ()=> _onThinkItemClick(item),
  164. child: Container(
  165. decoration: BoxDecoration(
  166. border: Border(bottom: BorderSide(width: 0.5, color: HexColor.fromHex('#EEEEEE')))
  167. ),
  168. padding: const EdgeInsets.only(top: 13, bottom: 13),
  169. child: Text('${item?.keywords}', style: TextStyle( color: HexColor.fromHex('#333333'), fontSize: 14),),
  170. ),
  171. );
  172. },
  173. itemCount: model?.length ?? 0,
  174. padding: const EdgeInsets.only(left: 12.5, right: 12.5),
  175. shrinkWrap: true,
  176. ),
  177. );
  178. }
  179. }