@@ -1,11 +1,11 @@ | |||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:flutter/material.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_bloc.dart'; | ||||
import 'package:zhiying_base_widget/pages/main_page/main_page_notifier.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: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 { | class MainPage extends StatefulWidget { | ||||
final Map<String, dynamic> data; | final Map<String, dynamic> data; | ||||
@@ -24,13 +24,11 @@ class _MainPageState extends State<MainPage> { | |||||
Widget build(BuildContext context) { | Widget build(BuildContext context) { | ||||
return Scaffold( | return Scaffold( | ||||
backgroundColor: Color(0xfff9f9f9), | 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>>( | return StreamBuilder<Map<String, dynamic>>( | ||||
stream: _bloc.outData, | stream: _bloc.outData, | ||||
builder: (BuildContext context, AsyncSnapshot snapshot) { | 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(); | List<Widget> list = List(); | ||||
for (int i = 0; i < model.components.length; i++) { | for (int i = 0; i < model.components.length; i++) { | ||||
WidgetModel item = model.components[i]; | WidgetModel item = model.components[i]; | ||||
Map<String, dynamic> data = null; | |||||
Map<String, dynamic> data = Map(); | |||||
if (widget.data.containsKey('components')) { | if (widget.data.containsKey('components')) { | ||||
data = widget.data['components'][i]; | 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/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_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/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_comm/zhiying_comm.dart'; | ||||
import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; | |||||
class BaseWidgetRegister { | class BaseWidgetRegister { | ||||
/// 初始化方法 | /// 初始化方法 | ||||
@@ -16,6 +19,7 @@ class BaseWidgetRegister { | |||||
static void registPage() { | static void registPage() { | ||||
PageFactory.regist('homePage', (model) => HomePage()); | PageFactory.regist('homePage', (model) => HomePage()); | ||||
PageFactory.regist('index', (model) => MainPage(model)); | 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('index_recommend_list', GoodsListCreater()); | ||||
// 首页快速入口 | // 首页快速入口 | ||||
WidgetFactory.regist('home_quick_entry', HomeQuickEntryCreater()); | 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() { | 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( | return RichText( | ||||
maxLines: 2, | maxLines: 2, | ||||
overflow: TextOverflow.ellipsis, | 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 != '') { | if (goods.coupon != null && goods.coupon != '') { | ||||
widgets.add(Container( | widgets.add(Container( | ||||
margin: EdgeInsets.only(right: 5), | 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( | decoration: BoxDecoration( | ||||
color: HexColor.fromHex(style.couponBackgroundColor), | color: HexColor.fromHex(style.couponBackgroundColor), | ||||
borderRadius: BorderRadius.circular(2.5), | borderRadius: BorderRadius.circular(2.5), | ||||
@@ -159,7 +157,7 @@ class HomeGoodsItem extends StatelessWidget { | |||||
if (goods.commission != null || goods.commission != '') { | if (goods.commission != null || goods.commission != '') { | ||||
widgets.add(Container( | widgets.add(Container( | ||||
margin: EdgeInsets.only(right: 5), | 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( | decoration: BoxDecoration( | ||||
color: HexColor.fromHex(style.commissionBackgroundColor), | color: HexColor.fromHex(style.commissionBackgroundColor), | ||||
borderRadius: BorderRadius.circular(2.5), | 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(), | |||||
)); | |||||
} | |||||
} |