import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:provider/provider.dart'; import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:color_thief_flutter/color_thief_flutter.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:twong/api/index.dart'; import 'package:twong/pages/tabs.dart'; import 'package:twong/utils/index.dart'; import 'package:twong/router/index.dart'; import 'package:twong/config/style.dart'; import 'package:twong/models/index.dart'; import 'package:twong/widgets/fsuper.dart'; import 'package:twong/providers/home.dart'; import 'package:twong/providers/message.dart'; import 'package:twong/utils/image_utils.dart'; import 'package:twong/widgets/search_bar.dart'; import 'package:twong/widgets/sliver_bar.dart'; import 'package:twong/widgets/product_item.dart'; class HomePage extends StatefulWidget { @override State createState() { return _HomePageState(); } } class _HomePageState extends State { Home _data; int _currentPage = 1; bool _checkColor = true; Color headerColor = Colors.red; ScrollController _controller = ScrollController(); @override initState() { super.initState(); loadData(); _controller.addListener(_onScroll); } loadData() async { _data = Cache.get(SaveKey.home); if(Cache.user == null) { Network.inst.autoLogin().then((res) { getData(); }); } else { getData(); } } getData() { Network.inst.getIndex().then((res) { setState(() { _data = Provider .of(context, listen: false) .data; headerColor = Provider .of(context, listen: false) .headerColor; }); Cache.set(SaveKey.home, _data); }); } _onSwipeChange(int index) async { if (!_checkColor) return; var image = CachedNetworkImageProvider(_data.banner[index].pic); getColorFromImage(await getImageFromProvider(image)).then((color) { var colors = Color.fromARGB(255, color[0], color[1], color[2]); var hsl = HSLColor.fromColor(colors); // 降低颜色亮度 colors = hsl.withLightness(hsl.lightness * 3 / 4).toColor(); setState(() { headerColor = colors; }); // Provider.of(context, listen: false).setHeaderColor(colors); }).catchError((err) { Log.d(err); }); } Widget _buildSlider (BuildContext context, int index) { var banner = _data.banner[index]; return CachedNetworkImage( fit: BoxFit.cover, imageUrl: banner.pic, imageBuilder: (BuildContext context, ImageProvider provider) { return GestureDetector( onTap: () { var id = banner.url.split("/")[2]; Navigator.pushNamed(context, RouteNames.productDetails, arguments: id); }, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(4.px), image: DecorationImage( image: provider, fit: BoxFit.cover ), ), ), ); }, placeholder: (BuildContext context, String str) { return Center(child: Utils.loadingWidget); }, ); } Widget _buildCate () { var buildBox = (String uri) { if (uri == null) { return Container( margin: EdgeInsets.all(4), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(3), ), ); } return InkWell( onTap: () {}, child: Container( margin: EdgeInsets.all(4), decoration: BoxDecoration( borderRadius: BorderRadius.circular(3), image: DecorationImage(image: CachedNetworkImageProvider(uri), fit: BoxFit.cover), ), ), ); }; return Container( margin: EdgeInsets.only(left: 4.px, right: 4.px), child: Row( children: [ Expanded(flex: 4, child: buildBox(null)), Expanded(flex: 6, child: Column( children: [ Expanded( child: buildBox(null)), Expanded( child: buildBox(null)), ], )) ], ), ); } Widget _buildNews () { return Container( height: 42.px, alignment: Alignment.center, child: Row( children: [ Container( margin: EdgeInsets.only(left: 12.px, right: 12.px), child: Text("资讯"), ), VerticalDivider(indent: 12.px, endIndent: 12.px, color: Colors.grey), Expanded(child: Container( margin: EdgeInsets.only(left: 12.px), child: Swiper( autoplay: true, physics: NeverScrollableScrollPhysics(), scrollDirection: Axis.vertical, itemBuilder: _buildNewsSlider, itemCount: _data.roll.length, autoplayDisableOnInteraction: true, ), )) ], ), ); } Widget _buildNewsSlider(BuildContext context, int index) { return Container( alignment: Alignment.centerLeft, child: Text(_data.roll[index]["info"]), ); } Widget _buildProducts () { if (_data.info.firstList.length > 0) { return SliverList( delegate: SliverChildBuilderDelegate((context, index) => ProductItem(_data.info.firstList[index]), childCount: _data.info.firstList.length), ); } else { return SliverToBoxAdapter( child: Container( alignment: Alignment.center, child: Text("暂时没有数据"), ), ); } } Widget _buildMenu() { var widgets = List(); for(var item in _data.menus) { widgets.add(Expanded( child: GestureDetector( onTap: () { Navigator.pushNamed(context, item.url); }, child: Container( alignment: Alignment.center, margin: EdgeInsets.all(10.px), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded(child: Container( width: 40.px, margin: EdgeInsets.only(bottom: 4.px), decoration: BoxDecoration( image: DecorationImage(image: CachedNetworkImageProvider(item.pic), fit: BoxFit.cover), borderRadius: BorderRadius.circular(10.px), ), )), Text(item.name, style: TextStyle(fontSize: 11.px),) ], ), )) )); } widgets.add(Expanded( child: GestureDetector( onTap: () { TabsState.inst.doItemTap(3); }, child: Container( alignment: Alignment.center, margin: EdgeInsets.all(10.px), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded(child: Container( width: 40.px, margin: EdgeInsets.only(bottom: 4.px), decoration: BoxDecoration( // image: DecorationImage(image: CachedNetworkImageProvider(""), fit: BoxFit.cover), borderRadius: BorderRadius.circular(10.px), ), )), Text(Cache.isVip ? "会员中心" : "用户中心", style: TextStyle(fontSize: 11.px)) ], ), )) )); return SliverToBoxAdapter( child: Container( height: 80.px, color: Colors.white, margin: EdgeInsets.all(6.px), child: Row( children: widgets, ), ) ); } List _buildDataList() { return [ SliverToBoxAdapter( child: Container( height: 150.px, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [headerColor, DColors.back], ), ), padding: EdgeInsets.only(left: 6.px, right: 6.px), child: Swiper( scale: 0.9, autoplay: true, duration: 600, autoplayDelay: 5600, itemBuilder: _buildSlider, itemCount: _data.banner.length, onIndexChanged: _onSwipeChange, pagination: SwiperPagination(), autoplayDisableOnInteraction: true, ) ) ), _buildMenu(), SliverToBoxAdapter( child: Container( height: 150.px, child: _buildCate() ), ), SliverToBoxAdapter( child: Container( height: 46.px, color: Colors.white, margin: EdgeInsets.all(6.px), child: _buildNews() ), ), SliverBar(), _buildProducts() ]; } _buildNoData() { return [ SliverToBoxAdapter( child: Container( height: 300.px, child: Center(child: Utils.loadingWidget) )) ]; } _buildBody() { return EasyRefresh.custom( onRefresh: _onRefresh, onLoad: _onLoad, bottomBouncing: true, scrollController: _controller, footer: BallPulseFooter(color: DColors.Main), header: BallPulseHeader(backgroundColor: headerColor, color: Colors.white), slivers: _data == null ? _buildNoData() : _buildDataList(), ); } Future _onLoad() async { _currentPage ++; Log.i("home list load more... page: $_currentPage}"); // return await Network.inst.getIndex().then((data){ // if(!mounted) return; // // _data = data; // // setState(() { // // _data.info.firstList.addAll(data.info.firstList.toList()); // // }); // }).catchError((err) {}); } Future _onRefresh() async { Log.i("refresh home"); // return await Network.inst.getIndex().then((data){ // // if(!mounted) return; // // setState(() { // // _data = data; // // }); // }).catchError((err) {}); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: DColors.back, appBar: SearchBar(null, color: headerColor, elevation: 0, actions: [ Consumer( builder: (context, message, child) { return FSuper( width: 38.px, height: double.infinity, onClick: () => Navigator.pushNamed(context, RouteNames.message), child1: Icon(IconFonts.message, color: Colors.white), child1Alignment: Alignment.centerLeft, redPoint: message.data.length > 0, redPointText: message.data.length.toString(), redPointOffset: Offset(-6.px, 0), redPointColor: Colors.white, redPointTextStyle: TextStyle(color: Colors.red, fontSize: 10.px, fontWeight: FontWeight.bold), ); }, ) ]), body: _buildBody(), floatingActionButton: _checkColor ? null : InkWell( onTap: () => _controller.animateTo(0, curve: Curves.ease, duration: Duration(milliseconds: 600)), child: Container( width: 32.px, height: 32.px, child: Icon( Icons.keyboard_arrow_up_sharp, color: Colors.white), decoration: BoxDecoration( color: Color.fromARGB(128, 243, 0, 0), borderRadius: BorderRadius.circular(10.px) ), ), ), ); } void _onScroll() { if (_checkColor && _controller.offset > 300) { _checkColor = false; } if (!_checkColor && _controller.offset < 300) { _checkColor = true; } } }