| @@ -1,11 +1,11 @@ | |||
| import 'package:flutter/cupertino.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:provider/provider.dart'; | |||
| import 'package:pull_to_refresh/pull_to_refresh.dart'; | |||
| import 'package:zhiying_base_widget/pages/main_page/main_page_bloc.dart'; | |||
| import 'package:zhiying_base_widget/pages/main_page/main_page_notifier.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| import 'package:provider/provider.dart'; | |||
| import 'package:zhiying_comm/util/base_bloc.dart'; | |||
| import 'package:pull_to_refresh/pull_to_refresh.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MainPage extends StatefulWidget { | |||
| final Map<String, dynamic> data; | |||
| @@ -24,13 +24,11 @@ class _MainPageState extends State<MainPage> { | |||
| Widget build(BuildContext context) { | |||
| return Scaffold( | |||
| backgroundColor: Color(0xfff9f9f9), | |||
| body: SafeArea( | |||
| child: ChangeNotifierProvider( | |||
| create: (context) => MainPageNotifier(), | |||
| child: BlocProvider<MainPageBloc>( | |||
| bloc: MainPageBloc(), | |||
| child: _MainPageContainer(widget.data), | |||
| ), | |||
| body: ChangeNotifierProvider( | |||
| create: (context) => MainPageNotifier(), | |||
| child: BlocProvider<MainPageBloc>( | |||
| bloc: MainPageBloc(), | |||
| child: _MainPageContainer(widget.data), | |||
| ), | |||
| ), | |||
| ); | |||
| @@ -89,17 +87,20 @@ class _MainPageContainerState extends State<_MainPageContainer> { | |||
| return StreamBuilder<Map<String, dynamic>>( | |||
| stream: _bloc.outData, | |||
| builder: (BuildContext context, AsyncSnapshot snapshot) { | |||
| return SmartRefresher( | |||
| enablePullDown: true, | |||
| enablePullUp: false, | |||
| header: WaterDropHeader(), | |||
| controller: _refreshController, | |||
| onLoading: _onLoading, | |||
| child: CustomScrollView( | |||
| controller: _controller, | |||
| slivers: _createContent(context), | |||
| ), | |||
| ); | |||
| return MediaQuery.removePadding( | |||
| removeTop: true, | |||
| context: context, | |||
| child: SmartRefresher( | |||
| enablePullDown: false, | |||
| enablePullUp: false, | |||
| header: WaterDropHeader(), | |||
| controller: _refreshController, | |||
| onLoading: _onLoading, | |||
| child: CustomScrollView( | |||
| controller: _controller, | |||
| slivers: _createContent(context), | |||
| ), | |||
| )); | |||
| }, | |||
| ); | |||
| } | |||
| @@ -110,7 +111,7 @@ class _MainPageContainerState extends State<_MainPageContainer> { | |||
| List<Widget> list = List(); | |||
| for (int i = 0; i < model.components.length; i++) { | |||
| WidgetModel item = model.components[i]; | |||
| Map<String, dynamic> data = null; | |||
| Map<String, dynamic> data = Map(); | |||
| if (widget.data.containsKey('components')) { | |||
| data = widget.data['components'][i]; | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| import 'package:flutter/cupertino.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| class MinePage extends StatefulWidget { | |||
| @override | |||
| _MinePageState createState() => _MinePageState(); | |||
| } | |||
| class _MinePageState extends State<MinePage> { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container(); | |||
| } | |||
| } | |||
| @@ -1,9 +1,12 @@ | |||
| import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; | |||
| import 'package:zhiying_base_widget/pages/main_page/main_page.dart'; | |||
| import 'package:zhiying_base_widget/widgets/home_goods/home_goods_creater.dart'; | |||
| import 'package:zhiying_base_widget/pages/mine_page//mine_page.dart'; | |||
| import 'package:zhiying_base_widget/widgets/home_banner/home_banner_creater.dart'; | |||
| import 'package:zhiying_base_widget/widgets/home_goods/home_goods_creater.dart'; | |||
| import 'package:zhiying_base_widget/widgets/home_quick_entry/home_quick_entry_creater.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine_header/mine_header_creater.dart'; | |||
| import 'package:zhiying_base_widget/widgets/others/mine_header_bg_creater.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; | |||
| class BaseWidgetRegister { | |||
| /// 初始化方法 | |||
| @@ -16,6 +19,7 @@ class BaseWidgetRegister { | |||
| static void registPage() { | |||
| PageFactory.regist('homePage', (model) => HomePage()); | |||
| PageFactory.regist('index', (model) => MainPage(model)); | |||
| PageFactory.regist('homePage', (profile) => MinePage()); | |||
| } | |||
| // 注册控件 | |||
| @@ -24,5 +28,9 @@ class BaseWidgetRegister { | |||
| WidgetFactory.regist('index_recommend_list', GoodsListCreater()); | |||
| // 首页快速入口 | |||
| WidgetFactory.regist('home_quick_entry', HomeQuickEntryCreater()); | |||
| // 个人中心 | |||
| // WidgetFactory.regist('index_title', MineHeaderCreater()); | |||
| // WidgetFactory.regist('index_search', MineHeaderBgCreater()); | |||
| // WidgetFactory.regist('index_search', MineQuickEntryCreater()); | |||
| } | |||
| } | |||
| @@ -70,38 +70,36 @@ class HomeGoodsItem extends StatelessWidget { | |||
| } | |||
| Widget _createTitle() { | |||
| List<InlineSpan> list = List(); | |||
| if (shop != null && shop != '') { | |||
| list.add(WidgetSpan( | |||
| child: Container( | |||
| padding: EdgeInsets.only(left: 2, right: 2, top: 3, bottom: 3), | |||
| margin: EdgeInsets.only(right: 4), | |||
| child: Text( | |||
| shop, | |||
| style: TextStyle( | |||
| fontSize: 9, | |||
| height: 1, | |||
| color: HexColor.fromHex('#ffffff'), | |||
| ), | |||
| ), | |||
| decoration: BoxDecoration( | |||
| color: Colors.red, borderRadius: BorderRadius.circular(2.5)), | |||
| ), | |||
| )); | |||
| } | |||
| list.add(TextSpan( | |||
| text: goods.goodTitle, | |||
| style: TextStyle( | |||
| fontSize: 15, | |||
| color: HexColor.fromHex('#333333'), | |||
| fontWeight: FontWeight.bold), | |||
| )); | |||
| return RichText( | |||
| maxLines: 2, | |||
| overflow: TextOverflow.ellipsis, | |||
| text: TextSpan(children: [ | |||
| WidgetSpan( | |||
| child: shop == null || shop == '' | |||
| ? Container() | |||
| : Container( | |||
| padding: | |||
| EdgeInsets.only(left: 2, right: 2, top: 3, bottom: 3), | |||
| margin: EdgeInsets.only(right: 4), | |||
| child: Text( | |||
| shop, | |||
| style: TextStyle( | |||
| fontSize: 9, | |||
| height: 1, | |||
| color: HexColor.fromHex('#ffffff'), | |||
| ), | |||
| ), | |||
| decoration: BoxDecoration( | |||
| color: Colors.red, | |||
| borderRadius: BorderRadius.circular(2.5)), | |||
| ), | |||
| ), | |||
| TextSpan( | |||
| text: goods.goodTitle, | |||
| style: TextStyle( | |||
| fontSize: 15, | |||
| color: HexColor.fromHex('#333333'), | |||
| fontWeight: FontWeight.bold), | |||
| ) | |||
| ]), | |||
| text: TextSpan(children: list), | |||
| ); | |||
| } | |||
| @@ -138,7 +136,7 @@ class HomeGoodsItem extends StatelessWidget { | |||
| if (goods.coupon != null && goods.coupon != '') { | |||
| widgets.add(Container( | |||
| margin: EdgeInsets.only(right: 5), | |||
| padding: EdgeInsets.only(left: 10, right: 10, top: 2, bottom: 2), | |||
| padding: EdgeInsets.only(left: 10, right: 10, top: 3, bottom: 3), | |||
| decoration: BoxDecoration( | |||
| color: HexColor.fromHex(style.couponBackgroundColor), | |||
| borderRadius: BorderRadius.circular(2.5), | |||
| @@ -159,7 +157,7 @@ class HomeGoodsItem extends StatelessWidget { | |||
| if (goods.commission != null || goods.commission != '') { | |||
| widgets.add(Container( | |||
| margin: EdgeInsets.only(right: 5), | |||
| padding: EdgeInsets.only(left: 10, right: 10, top: 2, bottom: 2), | |||
| padding: EdgeInsets.only(left: 10, right: 10, top: 3, bottom: 3), | |||
| decoration: BoxDecoration( | |||
| color: HexColor.fromHex(style.commissionBackgroundColor), | |||
| borderRadius: BorderRadius.circular(2.5), | |||
| @@ -0,0 +1,66 @@ | |||
| import 'dart:ui'; | |||
| import 'package:flutter/cupertino.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| class MineHeaderDelegate extends SliverPersistentHeaderDelegate { | |||
| double _height; | |||
| MineHeaderDelegate() : super() { | |||
| _height = MediaQueryData.fromWindow(window).padding.top + 44; | |||
| } | |||
| @override | |||
| Widget build( | |||
| BuildContext context, double shrinkOffset, bool overlapsContent) { | |||
| print('${shrinkOffset.toString()}'); | |||
| double percent = shrinkOffset / _height; | |||
| print('${percent.toString()}'); | |||
| return MineHeader(Colors.red.withOpacity(percent)); | |||
| } | |||
| @override | |||
| double get maxExtent => _height; | |||
| @override | |||
| double get minExtent => _height; | |||
| @override | |||
| bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => | |||
| false; // 如果内容需要更新,设置为true | |||
| } | |||
| class MineHeader extends StatelessWidget { | |||
| final Color color; | |||
| MineHeader(this.color); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container( | |||
| color: color, | |||
| child: Column( | |||
| children: <Widget>[ | |||
| Expanded(child: Container()), | |||
| Container( | |||
| width: double.infinity, | |||
| height: 44, | |||
| child: Row( | |||
| mainAxisAlignment: MainAxisAlignment.end, | |||
| crossAxisAlignment: CrossAxisAlignment.center, | |||
| children: <Widget>[ | |||
| Icon( | |||
| Icons.settings, | |||
| color: Colors.white, | |||
| ), | |||
| Icon( | |||
| Icons.chat, | |||
| color: Colors.white, | |||
| ) | |||
| ], | |||
| ), | |||
| ) | |||
| ], | |||
| )); | |||
| } | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine_header/mine_header.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MineHeaderCreater extends WidgetCreater { | |||
| @override | |||
| List<Widget> createWidgets(Map<String, dynamic> model) { | |||
| return [ | |||
| SliverPersistentHeader( | |||
| pinned: true, | |||
| floating: false, | |||
| delegate: MineHeaderDelegate(), | |||
| ), | |||
| ]; | |||
| } | |||
| @override | |||
| bool isSliverChild() { | |||
| return true; | |||
| } | |||
| } | |||
| @@ -0,0 +1,41 @@ | |||
| import 'dart:async'; | |||
| import 'package:zhiying_base_widget/widgets/mine_quick_entry/models/mine_quick_entry_model.dart'; | |||
| import 'package:zhiying_comm/util/base_bloc.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MineQuickEntryBloc extends BlocBase { | |||
| List<MineQuickEntryModel> _icons = List(); | |||
| StreamController<List<MineQuickEntryModel>> _iconsController = | |||
| StreamController<List<MineQuickEntryModel>>(); | |||
| Stream<List<MineQuickEntryModel>> get outData => _iconsController.stream; | |||
| @override | |||
| void dispose() { | |||
| _iconsController.close(); | |||
| _iconsController = null; | |||
| } | |||
| void loadData(int id) { | |||
| NetUtil.request('/api/v1/mod', | |||
| method: NetMethod.POST, | |||
| params: Map<String, dynamic>.from({ | |||
| 'ids': [id] | |||
| }), | |||
| onCache: (data) {}, onSuccess: (data) { | |||
| String key = id.toString(); | |||
| Map<String, dynamic> json = Map<String, dynamic>.from(data); | |||
| if (json.containsKey(key)) { | |||
| List<dynamic> list = json[key]; | |||
| _icons = list.map((item) { | |||
| return MineQuickEntryModel.fromJson(Map<String, dynamic>.from(item)); | |||
| }).toList(); | |||
| } | |||
| _iconsController.add(_icons); | |||
| }); | |||
| } | |||
| } | |||
| @@ -0,0 +1,51 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine_quick_entry/bloc/mine_quick_entry_bloc.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine_quick_entry/mine_quick_entry_sk.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine_quick_entry/models/mine_quick_entry_model.dart'; | |||
| import 'package:zhiying_comm/util/base_bloc.dart'; | |||
| class MineQuickEntry extends StatefulWidget { | |||
| @override | |||
| _MineQuickEntryState createState() => _MineQuickEntryState(); | |||
| } | |||
| class _MineQuickEntryState extends State<MineQuickEntry> { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return BlocProvider<MineQuickEntryBloc>( | |||
| bloc: MineQuickEntryBloc(), | |||
| child: _MineQuickEntryContainer(), | |||
| ); | |||
| } | |||
| } | |||
| class _MineQuickEntryContainer extends StatefulWidget { | |||
| @override | |||
| _MineQuickEntryContainerState createState() => | |||
| _MineQuickEntryContainerState(); | |||
| } | |||
| class _MineQuickEntryContainerState extends State<_MineQuickEntryContainer> { | |||
| MineQuickEntryBloc _bloc; | |||
| @override | |||
| void initState() { | |||
| _bloc = BlocProvider.of<MineQuickEntryBloc>(context); | |||
| _bloc.loadData(4); | |||
| super.initState(); | |||
| } | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return StreamBuilder<List<MineQuickEntryModel>>( | |||
| stream: _bloc.outData, | |||
| builder: (BuildContext context, AsyncSnapshot snapshot) { | |||
| if (snapshot.data == null) { | |||
| return MineQuickEntrySkeleton(); | |||
| } | |||
| return MineQuickEntrySkeleton(); | |||
| }); | |||
| } | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/mine_quick_entry/mine_quick_entry.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MineQuickEntryCreater extends WidgetCreater { | |||
| @override | |||
| List<Widget> createWidgets(Map<String, dynamic> model) { | |||
| return [ | |||
| MineQuickEntry(), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -0,0 +1,53 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:shimmer/shimmer.dart'; | |||
| class MineQuickEntrySkeleton extends StatelessWidget { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container( | |||
| width: double.infinity, | |||
| decoration: BoxDecoration( | |||
| borderRadius: BorderRadius.circular(7.5), color: Colors.white), | |||
| // margin: EdgeInsets.only(left: 12.5, right: 12.5), | |||
| child: Shimmer.fromColors( | |||
| baseColor: Colors.grey[300], | |||
| highlightColor: Colors.grey[100], | |||
| child: GridView.builder( | |||
| shrinkWrap: true, | |||
| physics: NeverScrollableScrollPhysics(), | |||
| gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( | |||
| crossAxisCount: 4, | |||
| crossAxisSpacing: 1, | |||
| mainAxisSpacing: 1, | |||
| childAspectRatio: 1, | |||
| ), | |||
| itemCount: 8, | |||
| itemBuilder: (BuildContext context, int index) { | |||
| return Container( | |||
| child: Center( | |||
| child: Column( | |||
| mainAxisAlignment: MainAxisAlignment.center, | |||
| children: <Widget>[ | |||
| Container( | |||
| width: 36, | |||
| height: 36, | |||
| margin: EdgeInsets.only(bottom: 4), | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, | |||
| borderRadius: BorderRadius.circular(18)), | |||
| ), | |||
| Container( | |||
| width: 24, | |||
| height: 12, | |||
| color: Colors.white, | |||
| ) | |||
| ], | |||
| ), | |||
| ), | |||
| ); | |||
| }, | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,3 @@ | |||
| class MineQuickEntryModel { | |||
| static fromJson(Map map) {} | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/others/mine_header_bg_widget.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class MineHeaderBgCreater extends WidgetCreater { | |||
| @override | |||
| List<Widget> createWidgets(Map<String, dynamic> model) { | |||
| return [ | |||
| MineHeaderBgWidget(), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -0,0 +1,70 @@ | |||
| import 'dart:async'; | |||
| import 'package:cached_network_image/cached_network_image.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| class MineHeaderBgWidget extends StatefulWidget { | |||
| @override | |||
| _MineHeaderBgWidgetState createState() => _MineHeaderBgWidgetState(); | |||
| } | |||
| class _MineHeaderBgWidgetState extends State<MineHeaderBgWidget> { | |||
| int zIndex = 0; | |||
| // List<String> list = ['ff0000', '00ff00', '0000ff', 'ffff00']; | |||
| List<String> imageUrls = [ | |||
| 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1599627593136&di=2aa824f43d4945dbeca31d5ccc587567&imgtype=0&src=http%3A%2F%2Ft8.baidu.com%2Fit%2Fu%3D1484500186%2C1503043093%26fm%3D79%26app%3D86%26f%3DJPEG%3Fw%3D1280%26h%3D853', | |||
| 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1599627593136&di=c082ab4b39f0bc45e8cad60447db4ae2&imgtype=0&src=http%3A%2F%2Ft8.baidu.com%2Fit%2Fu%3D2247852322%2C986532796%26fm%3D79%26app%3D86%26f%3DJPEG%3Fw%3D1280%26h%3D853', | |||
| 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1599627593136&di=b7535e61ed661806647bf1070e74f883&imgtype=0&src=http%3A%2F%2Ft7.baidu.com%2Fit%2Fu%3D3204887199%2C3790688592%26fm%3D79%26app%3D86%26f%3DJPEG%3Fw%3D4610%26h%3D2968', | |||
| 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1599627593136&di=3b381359676404f5e42f6a663a0139f1&imgtype=0&src=http%3A%2F%2Ft9.baidu.com%2Fit%2Fu%3D3363001160%2C1163944807%26fm%3D79%26app%3D86%26f%3DJPEG%3Fw%3D1280%26h%3D830', | |||
| ]; | |||
| Timer timer; | |||
| //setInterval控制当前动画元素的下标,实现动画轮播 | |||
| autoPlay() { | |||
| var second = const Duration(seconds: 2); | |||
| timer = Timer.periodic(second, (t) { | |||
| setState(() { | |||
| zIndex = (++zIndex) % imageUrls.length; | |||
| }); | |||
| }); | |||
| } | |||
| @override | |||
| void initState() { | |||
| super.initState(); | |||
| timer = Timer(Duration(seconds: 2), autoPlay); | |||
| } | |||
| @override | |||
| void dispose() { | |||
| if (timer != null) timer.cancel(); | |||
| super.dispose(); | |||
| } | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container( | |||
| height: 300, | |||
| width: double.infinity, | |||
| child: Stack( | |||
| children: imageUrls | |||
| .asMap() | |||
| .keys | |||
| .map<Widget>((i) => AnimatedOpacity( | |||
| curve: Curves.easeIn, | |||
| duration: Duration(milliseconds: 1600), | |||
| opacity: i == zIndex ? 1 : 0, | |||
| child: Container( | |||
| // color: Color(int.parse(list[i], radix: 16)) | |||
| // .withAlpha(255), | |||
| child: CachedNetworkImage( | |||
| imageUrl: imageUrls[i], | |||
| ), | |||
| height: 300, //100% | |||
| ), | |||
| )) | |||
| .toList(), | |||
| )); | |||
| } | |||
| } | |||