import 'package:bot_toast/bot_toast.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:color_thief_flutter/color_thief_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_app_upgrade/flutter_app_upgrade.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:package_info/package_info.dart'; import 'package:provider/provider.dart'; import 'package:twong/api/index.dart'; import 'package:twong/providers/home_model.dart'; import 'package:twong/router/index.dart'; import 'package:twong/config/style.dart'; import 'package:twong/models/index.dart'; import 'package:twong/utils/image_utils.dart'; import 'package:twong/utils/index.dart'; import 'package:twong/widgets/future_widget.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; bool _checkColor = true; Color headerColor = Colors.red; ScrollController _controller = ScrollController(); @override initState() { super.initState(); initData(); _controller.addListener(_onScroll); } initData() async { _data = Cache.get(SaveKey.home); Network.inst.getIndex().then((data) { if(!mounted) return; setState(() { _data = data; }); Cache.set(SaveKey.home, _data); }).catchError((err) { print(err); }); } _onSwipeChange(int index) async { if (!_checkColor) return; // todo 测试数据 var colors = [ Colors.red, Colors.green ]; getColorFromUrl(_data.banner[index].pic).then((color) { setState(() { headerColor = colors[index]; }); }); } 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: CircularProgressIndicator()); }, ); } 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 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( alignment: Alignment.center, child: Text("新闻资讯"), ); } Widget _buildProducts () { if (_data.info.firstList.length > 0) { return SliverList( delegate: SliverChildBuilderDelegate((context, index) => ProductItem(index, _data?.info?.firstList), 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),) ], ), )) )); } var isVip = Cache.user != null && Cache.user.vip_level > 1; widgets.add(Expanded( child: GestureDetector( onTap: () { Navigator.pushNamed(context, "user"); }, 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(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, 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: 40.px, color: Colors.white, margin: EdgeInsets.all(6.px), child: _buildNews() ), ), SliverBar(), SliverPadding( padding: EdgeInsets.all(6.px), sliver: _buildProducts() ) ]; } _buildNoData() { return [ SliverToBoxAdapter( child: Container( height: 300.px, child: Center(child: CircularProgressIndicator()) )) ]; } _buildBody() { // var headerColor = Provider.of(context, listen: false).headerColor; 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 { Log.i("home list load more..."); 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: [ GestureDetector(onTap: () { Navigator.pushNamed(context, RouteNames.message); }, child: Container( margin: EdgeInsets.only(right: 12.px), child: Icon(IconFonts.message), )) ]), body: _buildBody(), floatingActionButton: _checkColor ? null : InkWell( onTap: () => _controller.animateTo(0, duration: Duration(milliseconds: 600), curve: Curves.ease), 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) { setState(() { _checkColor = false; }); } if (!_checkColor && _controller.offset < 300) { setState(() { _checkColor = true; }); } } }