基础组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

190 lines
5.7 KiB

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