import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:liftmanager/internal/bbs/model/expert_model.dart' as ExportModel; import 'package:liftmanager/internal/bbs/model/mix_model.dart'; import 'package:liftmanager/internal/bbs/presenter/question_list_presenter.dart'; import 'package:liftmanager/internal/search/presenter/base_list_provider.dart'; import 'package:liftmanager/mvp/base_page_state.dart'; import 'package:liftmanager/net/api_service.dart'; import 'package:liftmanager/res/iconfont.dart'; import 'package:liftmanager/res/resources.dart'; import 'package:liftmanager/utils/theme_utils.dart'; import 'package:liftmanager/utils/toast.dart'; import 'package:liftmanager/widgets/app_search_bar.dart'; import 'package:liftmanager/widgets/bbs_content.dart'; import 'package:liftmanager/widgets/divider.dart'; import 'package:liftmanager/widgets/load_image.dart'; import 'package:liftmanager/widgets/my_refresh_list.dart'; import 'package:liftmanager/widgets/state_layout.dart'; import 'package:provider/provider.dart'; import '../../brand_page.dart'; class QuestionList extends StatefulWidget { @override QuestionListState createState() => QuestionListState(); } class QuestionListState extends BasePageState { BaseListProvider provider = BaseListProvider(); ScrollController _scrollController = new ScrollController(); int _page = 1; int selectedBrandId; bool showBrandSelectionPanel = false; bool showExpertSelectionPanel = false; String selectedBrandName; String selectedExpertName; String searchWord; List brandList; Map> groupedExpertList; @override void initState() { provider.setStateTypeNotNotify(StateType.loading); super.initState(); _onRefresh(); } Future getBrandList() async { await NewApiService().getBrandListType(null, onSuccess: (res) { if (res != null) { brandList = res; setState(() {}); } }, onError: (code, msg) { toasts(msg); }); } Future getExpertList() async { await NewApiService().getExpertListGrouped(onSuccess: (res) { if (res.listGroup != null) { groupedExpertList = res.listGroup; setState(() {}); } }, onError: (code, msg) { toasts(msg); }); } @override void dispose() { _scrollController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { double width = MediaQuery.of(context).size.width; double height = MediaQuery.of(context).size.height; return ChangeNotifierProvider>( create: (_) => provider, child: Scaffold( appBar: SearchAppBar2( backgroundColor: Colors.white, onPressed: (text) { searchWord = text; _onRefresh(); }, ), body: Container( child: Stack(children: [ Column( children: [ Container( // alignment: Alignment.center, width: width, height: ScreenUtil().setWidth(50), decoration: BoxDecoration( border: Border( bottom: BorderSide(width: 0.5, color: Colours.line), ), ), padding: EdgeInsets.only( left: ScreenUtil().setWidth(15), right: ScreenUtil().setWidth(15)), // color: Color(0xFFF1F4FC), child: Row( children: [ Expanded( child: Container( alignment: Alignment.center, child: GestureDetector( onTap: () { getBrandList(); setState(() { showBrandSelectionPanel = !showBrandSelectionPanel; showExpertSelectionPanel = false; }); }, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( selectedBrandName ?? '品牌', style: TextStyle( fontSize: ScreenUtil().setSp(16), color: showBrandSelectionPanel ? Colors.blue : Colors.black, ), textAlign: TextAlign.center, ), Container( // padding: EdgeInsets.only(top: 3), child: Icon( showBrandSelectionPanel ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, size: 26.0, color: showBrandSelectionPanel ? Colors.blue : Colors.black, ), ), SizedBox(width: 10,), if (showBrandSelectionPanel && selectedBrandName != null) GestureDetector( onTap: (){ setState(() { showBrandSelectionPanel = false; selectedBrandName = null; selectedBrandId = null; provider.setStateTypeNotNotify(StateType.loading); _onRefresh(); }); }, child: Container( padding: EdgeInsets.only(bottom: 3), child: Icon( Iconfont.shanchu1, size: 16.0, color: Colors.blue, ), ), ), ], ), ), ), ), CzDivider( height: ScreenUtil().setHeight(15), width: 2, ), // SizedBox(width: ScreenUtil().setWidth(30)), Expanded( child: GestureDetector( onTap: () { getExpertList(); setState(() { showExpertSelectionPanel = !showExpertSelectionPanel; showBrandSelectionPanel = false; }); }, child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( selectedExpertName ?? '专家', style: TextStyle( fontSize: ScreenUtil().setSp(16), color: showExpertSelectionPanel ? Colors.blue : Colors.black, ), textAlign: TextAlign.center, ), Container( // padding: EdgeInsets.only(top: 3), child: Icon( showExpertSelectionPanel ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, size: 26.0, color: showExpertSelectionPanel ? Colors.blue : Colors.black), ), SizedBox(width: 10,), if (showExpertSelectionPanel && selectedExpertName != null) GestureDetector( onTap: (){ setState(() { showExpertSelectionPanel = false; selectedExpertName = null; provider.setStateTypeNotNotify(StateType.loading); _onRefresh(); }); }, child: Container( padding: EdgeInsets.only(bottom: 3), child: Icon( Iconfont.shanchu1, size: 16.0, color: Colors.blue, ), ), ), ], ), ), ) ], )), Expanded( flex: 1, child: Consumer>( builder: (_, provider, __) { return MyListView( key: Key('question_list'), itemCount: provider.list.length, stateType: provider.stateType, onRefresh: _onRefresh, pageSize: 10, loadMore: _loadMore, hasMore: provider.hasMore, padding: EdgeInsets.symmetric(horizontal: 10), itemBuilder: (_, index) { return QuestionCell(item: provider.list[index]); }, ); })) ], ), if (showBrandSelectionPanel) Positioned.fill( top: 50, left: 0, child: Container( color: Colors.white, child: brandList != null ? BrandSelectionPanel( brandList: brandList, onTapBrand: (records) { setState(() { selectedBrandName = records.name; selectedBrandId = records.id; provider.setStateTypeNotNotify(StateType.loading); _onRefresh(); showBrandSelectionPanel = false; }); }, ) : loadCircle(), ), ), if (showExpertSelectionPanel) Positioned.fill( top: 50, left: 0, child: Container( color: ThemeUtils.getDialogTextFieldColor(context), child: groupedExpertList != null ? ExpertSelectionPanel( listGroup: groupedExpertList, onTapExpertCell: (model) { setState(() { selectedExpertName = model.name; showExpertSelectionPanel = false; provider.setStateTypeNotNotify(StateType.loading); _onRefresh(); }); }, ) : loadCircle(), ), ), ]), ), ), ); } Widget loadCircle() { return Container( padding: EdgeInsets.only(top: 10, bottom: 10), color: ThemeUtils.getTabsBg(context), child: Center( child: SpinKitFadingCircle( color: Colors.blueAccent, size: 30.0, ), ), ); } Future _onRefresh() async { _page = 1; await presenter.getQuestionList( _page, selectedBrandId, selectedExpertName, searchWord); } Future _loadMore() async { _page++; await presenter.getQuestionList( _page, selectedBrandId, selectedExpertName, searchWord); } @override QuestionListPresenterSeconds createPresenter() { return QuestionListPresenterSeconds(); } } class ExpertSelectionPanel extends StatelessWidget { final Map> listGroup; final Function(ExportModel.Records model) onTapExpertCell; final _positionAnchors = {}; final _controller = ScrollController(); ExpertSelectionPanel({Key key, this.listGroup, this.onTapExpertCell}) : super(key: key) { double offset = 0; var sectionHeaderHeight = 30.0; var sectionCellHeight = 80.0; for (var key in listGroup.keys) { _positionAnchors[key] = offset; offset += sectionHeaderHeight + sectionCellHeight * listGroup[key].length; } } @override Widget build(BuildContext context) { return Stack( alignment: Alignment.center, children: [ ListView.builder( itemCount: listGroup.keys.length, controller: _controller, itemBuilder: (context, index) { return Column( children: [ ExpertSection( title: listGroup.keys.elementAt(index), expertList: listGroup[listGroup.keys.elementAt(index)], onTapExpertCell: onTapExpertCell, ), ], ); }), Positioned( right: 0, child: AlphabeticIndexBar( controller: _controller, positionAnchors: _positionAnchors, ), ), ], ); } } class ExpertSection extends StatelessWidget { final String title; final List expertList; final Function(ExportModel.Records model) onTapExpertCell; const ExpertSection( {Key key, this.title, this.expertList, this.onTapExpertCell}) : super(key: key); @override Widget build(BuildContext context) { return Column(children: [ Container( height: 30, child: CommonSectionHeader( title: title, ), ), ...expertList .map((e) => ExpertCell( model: e, onTap: onTapExpertCell, )) .toList(), ]); } } class ExpertCell extends StatelessWidget { final ExportModel.Records model; final Function(ExportModel.Records model) onTap; const ExpertCell({Key key, this.model, this.onTap}) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( onTap: () { if (onTap != null) { onTap(model); } }, child: Container( color: Colors.white, height: 80, padding: EdgeInsets.only(right: 30), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: 10, ), ClipRRect( borderRadius: BorderRadius.circular(24), child: LoadNetworkImage( model.avatarUrl, width: 48, height: 48, ), ), SizedBox( width: 10, ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(model.name ?? ''), SizedBox( height: 10, ), Text(model.proficiencyBrand ?? ''), ], ), ), ], ), ), ); } }