@@ -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(), | |||
)); | |||
} | |||
} |