Commit 1cb532f5 authored by 杜欣's avatar 杜欣

Merge branch 'test' into featrue/duxin

parents f3daabf2 677bfbe3
...@@ -18,6 +18,9 @@ abstract class ClueRouter implements RouterBaser { ...@@ -18,6 +18,9 @@ abstract class ClueRouter implements RouterBaser {
Widget getLevelTwoPage(); Widget getLevelTwoPage();
Widget getPlanPage(); Widget getPlanPage();
Widget getPlanCompareDetailPage(); Widget getPlanCompareDetailPage();
Widget getTopPage();
} }
...@@ -10,6 +10,7 @@ import 'package:gm_flutter/ClueModel/page/levelOne/LevelOnePage.dart'; ...@@ -10,6 +10,7 @@ import 'package:gm_flutter/ClueModel/page/levelOne/LevelOnePage.dart';
import 'package:gm_flutter/ClueModel/page/levelTwo/LevelTwoPage.dart'; import 'package:gm_flutter/ClueModel/page/levelTwo/LevelTwoPage.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanPage.dart'; import 'package:gm_flutter/ClueModel/page/plan/PlanPage.dart';
import 'package:gm_flutter/ClueModel/page/PlanCompareDetail/PlanCompareDetailPage.dart'; import 'package:gm_flutter/ClueModel/page/PlanCompareDetail/PlanCompareDetailPage.dart';
import 'package:gm_flutter/ClueModel/page/top/TopPage.dart';
class ClueRouterImpl implements ClueRouter { class ClueRouterImpl implements ClueRouter {
@override @override
...@@ -40,4 +41,9 @@ class ClueRouterImpl implements ClueRouter { ...@@ -40,4 +41,9 @@ class ClueRouterImpl implements ClueRouter {
Widget getPlanCompareDetailPage() { Widget getPlanCompareDetailPage() {
return PlanCompareDetailPage(); return PlanCompareDetailPage();
} }
@override
Widget getTopPage() {
return TopPage();
}
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: zx * @Author: zx
* @Date: 2020-06-30 17:43:13 * @Date: 2020-06-30 17:43:13
* @Last Modified by: zx * @Last Modified by: zx
* @Last Modified time: 2020-07-01 20:04:23 * @Last Modified time: 2020-07-02 13:50:15
*/ */
import 'package:flutter_common/commonModel/live/BaseModel.dart'; import 'package:flutter_common/commonModel/live/BaseModel.dart';
import 'package:flutter_common/commonModel/live/LiveData.dart'; import 'package:flutter_common/commonModel/live/LiveData.dart';
...@@ -10,25 +10,49 @@ import 'package:gm_flutter/ClueModel/server/api/ClueApi.serv.dart'; ...@@ -10,25 +10,49 @@ import 'package:gm_flutter/ClueModel/server/api/ClueApi.serv.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart'; import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart';
import 'package:gm_flutter/commonModel/GMBase.dart'; import 'package:gm_flutter/commonModel/GMBase.dart';
import 'package:gm_flutter/commonModel/rx/RxDispose.dart'; import 'package:gm_flutter/commonModel/rx/RxDispose.dart';
import 'package:flutter_common/commonModel/toast/NativeToast.dart';
import 'package:gm_flutter/commonModel/util/PrintUtil.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
class PlanCompareDetailModel extends BaseModel { class PlanCompareDetailModel extends BaseModel {
LiveData<PlanCompareDetail> detailLive = LiveData(); LiveData<Pair<int, List<Groups>>> detailLive = LiveData();
LiveData<Pair<int, List<PlansInfo>>> headerLive = LiveData();
LiveData<int> stateLive = LiveData();
RxDispose rxDispose = RxDispose(); RxDispose rxDispose = RxDispose();
void init() { void init(List<int> planIds) {
ClueApiImpl.getInstance() ClueApiImpl.getInstance()
.getPlanCompareDetail(DioUtil.getInstance().getDio(), [1,2]) .getPlanCompareDetail(DioUtil.getInstance().getDio(), planIds)
.listen((event) { .listen((event) {
if (event.error == 0) { if (event.error == 0) {
detailLive.notifyView(event); stateLive.notifyView(ENDLOADING);
if (event.data.plansInfo == null || event.data.groups.isEmpty) {
headerLive.notifyView(Pair(ENDLOADING, []));
detailLive.notifyView(Pair(ENDLOADING, []));
} else {
detailLive.notifyView(Pair(ENDLOADING, event.data.groups));
headerLive.notifyView(Pair(ENDLOADING, event.data.plansInfo));
}
} else {
stateLive.notifyView(FAIL);
NativeToast.showNativeToast(event.message);
headerLive.notifyView(Pair(FAIL, null));
detailLive.notifyView(Pair(FAIL, null));
} }
}) })
.addToDispose(rxDispose) .addToDispose(rxDispose)
.onError((err) {}); .onError((err) {
stateLive.notifyView(FAIL);
headerLive.notifyView(Pair(FAIL, null));
detailLive.notifyView(Pair(FAIL, null));
NativeToast.showNativeToast(err.message);
});
} }
@override @override
void dispose() { void dispose() {
stateLive.dispost();
detailLive.dispost(); detailLive.dispost();
} }
}
}
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* @Author: zx * @Author: zx
* @Date: 2020-06-30 17:40:43 * @Date: 2020-06-30 17:40:43
* @Last Modified by: zx * @Last Modified by: zx
* @Last Modified time: 2020-07-01 22:11:20 * @Last Modified time: 2020-07-02 18:44:20
*/ */
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
...@@ -14,34 +14,27 @@ import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart'; ...@@ -14,34 +14,27 @@ import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart';
import 'package:gm_flutter/ClueModel/view/FiveStarView.dart'; import 'package:gm_flutter/ClueModel/view/FiveStarView.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart'; import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/base/BaseState.dart'; import 'package:gm_flutter/commonModel/base/BaseState.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
class PlanCompareDetailPage extends StatefulWidget { class PlanCompareDetailPage extends StatefulWidget {
@override @override
State<StatefulWidget> createState() => PlanCompareDetailPageState(); State<StatefulWidget> createState() => PlanCompareDetailPageState();
} }
class PlanCompareDetailPageState extends BaseState<PlanCompareDetailPage> { class PlanCompareDetailPageState extends BaseState<PlanCompareDetailPage> {
PlanCompareDetailModel _model = new PlanCompareDetailModel(); PlanCompareDetailModel _model = new PlanCompareDetailModel();
PageController pageController = new PageController(); double screenWidth;
double screenWidth;
List<Widget> viewList = new List(); List<Widget> viewList = new List();
@override
@override
void initState() { void initState() {
super.initState(); super.initState();
pageController.addListener(() { _model.init([1, 2]);
});
Groups groups;
viewList.add(planNormalEffectiveAttrsView(groups));
viewList.add(planNormalEffectiveAttrsView(groups));
viewList.add(planNormalEffectiveAttrsView(groups));
} }
@override @override
void dispose() { void dispose() {
_model.dispose(); _model.dispose();
pageController.dispose();
pageController.dispose();
super.dispose(); super.dispose();
} }
...@@ -49,415 +42,361 @@ class PlanCompareDetailPageState extends BaseState<PlanCompareDetailPage> { ...@@ -49,415 +42,361 @@ class PlanCompareDetailPageState extends BaseState<PlanCompareDetailPage> {
Widget buildItem(BuildContext context) { Widget buildItem(BuildContext context) {
screenWidth = MediaQuery.of(context).size.width; screenWidth = MediaQuery.of(context).size.width;
return Scaffold( return Scaffold(
appBar: baseAppBar( appBar: baseAppBar(
title: "对比详情", title: "对比详情",
centerTitle: true, centerTitle: true,
backClick: () { backClick: () {
Navigator.pop(context); Navigator.pop(context);
}), }),
body: Container( body: Container(
child: child:
// planPopularityView() // head(),
// planNormalEffectiveAttrsView()
// setupHome([], []), // planPopularityView()
reloadPage(), // planNormalEffectiveAttrsView()
// setupHome([], []),
) reloadPage(),
); ));
} }
Widget reloadPage () { Widget reloadPage() {
return StreamBuilder( return StreamBuilder(
stream: _model.detailLive.stream, stream: _model.stateLive.stream,
initialData: PlanCompareDetail(), initialData: _model.stateLive.data ?? LOADING,
builder: (c, data) { builder: (c, data) {
PlanCompareDetail detail = data.data; if (data.data == FAIL) {
if (detail == null || detail.data == null || detail.data.groups == null) { return errorItem(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height, () {
_model.init([1, 2]);
});
}
if (data.data == LOADING) {
return loadingItem(); return loadingItem();
} }
return setupHome(detail.data.plansInfo, detail.data.groups); return setupHome();
}, },
); );
} }
Widget setupHome(List<PlansInfo> plansInfo, List<Groups> groups) { Widget setupHome() {
return Column( return Column(
children: <Widget>[ children: <Widget>[
head(),
Expanded( Expanded(
child: Stack( child: Container(
children: <Widget>[ child: StreamBuilder<Pair<int, List<Groups>>>(
head(plansInfo), stream: _model.detailLive.stream,
Expanded ( initialData: _model.detailLive.data ?? Pair(LOADING, null),
child: Container( builder: (c, data) {
margin: EdgeInsets.fromLTRB(15, 105, 15, 0), if (data.data.first == FAIL) {
child: return errorItem(MediaQuery.of(context).size.width,
// ListView.builder( MediaQuery.of(context).size.height, () {
// itemBuilder: (BuildContext context, int index) { //TODO
// Groups group = groups[index]; });
// switch (group.groupType) { }
// case 'hot': return ListView.builder(
// return planPopularityView(group); itemBuilder: (BuildContext context, int index) {
// break; if (index == data.data.second.length * 2 - 1) {
// case 'normal_attrs': return Container(
// return planNormalEffectiveAttrsView(group); height: 40,
// break; color: Color(0xffF7F6FA),
// case 'effective_attrs': );
// return planNormalEffectiveAttrsView(group); }
// break; if (index % 2 != 0) {
// default: return Container(
// return planNormalEffectiveAttrsView(group); height: 5,
// } color: Color(0xffF7F6FA),
// }, );
// itemCount: groups.length, }
// ) int newIndex = (index / 2).floor();
CustomScrollView( Groups group = data.data.second[newIndex];
slivers: <Widget>[ Widget widget;
SliverList( if (group.groupType == 'hot') {
delegate: SliverChildBuilderDelegate( widget = Container(
(BuildContext context, int index) { height: 100,
return viewList[index]; alignment: Alignment.center,
}, child: baseText("第一个", 15, Colors.black),
childCount: viewList.length, );
), } else if (group.groupType == 'normal_attrs') {
), widget = Container(
], child: planNormalEffectiveAttrsView(group),
), );
) } else if (group.groupType == 'effective_attrs') {
), widget = Container(
child: planNormalEffectiveAttrsView(group),
], );
), } else {
) widget = planNormalEffectiveAttrsView(group);
}
return Container(
margin: EdgeInsets.only(left: 15, right: 15),
child: widget,
);
},
itemCount: data.data.second.length * 2,
);
}),
))
], ],
); );
} }
Widget head(List<PlansInfo> plansInfo) { Widget head() {
PlansInfo plan;
return Container( return Container(
// key: keyTop, // key: keyTop,
color: Colors.yellow,
width: screenWidth, width: screenWidth,
height: 105, height: 105,
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
margin: EdgeInsets.fromLTRB(9.5, 0, 9.5, 0), margin: EdgeInsets.only(left: 15, right: 15),
child: Row(children: <Widget>[ child: Row(children: <Widget>[
// 根据 flex系数,分配剩余空间 // 根据 flex系数,分配剩余空间
Expanded( Expanded(flex: 1, child: headItem(0)),
flex:1, Expanded(flex: 1, child: headItem(1))
child: headItem(plan) ]),
), );
Expanded(
flex: 1,
child: headItem(plan)
)
]
),
);
} }
Widget headItem(PlansInfo plan) { Widget headItem(int index) {
return Container( return StreamBuilder(
child: Stack( stream: _model.headerLive.stream,
children: <Widget>[ initialData: _model.headerLive.data ?? null,
Positioned( builder: (c, data) {
child: Container( if (data.data == null) {
margin: EdgeInsets.fromLTRB(5.5, 15, 5.5, 15), return Container();
width: (screenWidth - 41) / 2.0, }
// child: Text('1111111'), return Container(
decoration: BoxDecoration( child: Stack(children: <Widget>[
borderRadius: BorderRadius.circular(7.0), Positioned(
image: top: 8,
DecorationImage( left: index == 0 ? 0 : 5.5,
fit: BoxFit.cover, child: Container(
image: NetworkImage( height: 75,
"https://pic.igengmei.com/2018/09/11/1513/b7e825a4e4c1-w") width: (screenWidth - 30 - 11) / 2,
) child: ClipRRect(
) borderRadius: BorderRadius.circular(15),
), child: Image.asset('assets/plan_compare_detail_info_bg.png',
fit: BoxFit.cover),
), ),
Positioned( )),
left: 17.5, Positioned(
top: 31, left: 12,
child: baseText('11111', 15, Color(0xff333333), top: 24,
bold: true), child: baseText('11111', 15, Color(0xff333333), bold: true),
), ),
Positioned(
Positioned( left: 12,
left: 17.5, top: 48,
bottom: 31, child: baseText('¥¥¥¥¥¥¥¥¥¥', 14, Colors.red, bold: true),
child: baseText('¥¥¥¥¥¥¥¥¥¥', 14, Colors.red, ),
bold: true), ]));
), },
]
)
); );
} }
Widget titleView() {
Widget titleView(String title) {
return Container( return Container(
height: 81, height: 75,
width: screenWidth, width: screenWidth,
color: Colors.cyan, margin: EdgeInsets.fromLTRB(0, 30, 0, 20),
margin: EdgeInsets.fromLTRB(0, 30, 0, 13), alignment: Alignment.center,
alignment: Alignment.topCenter,
child: Container( child: Container(
child: baseText('基础属性', 21, Colors.black, bold: true), width: 90,
), height: 25,
); child: Stack(
} alignment: AlignmentDirectional.center,
children: <Widget>[
Widget planPopularityView() { Positioned(
return Container( bottom: 0,
color: Colors.green, child: Container(
height: 265, width: 90,
child: Container ( height: 10,
child: Column( child: Image.asset("assets/plan_compare_detail_title_bg.png"),
children: <Widget>[ ),
titleView(), ),
Row( Positioned(
children: <Widget>[ top: 0,
Expanded( child: baseText(title, 21, Color(0xff282828), bold: true),
flex:1,
child: planPopularityLeftItem()
),
Expanded(
flex: 1,
child: planPopularityRightItem()
)
]
) )
] ],
) ),
), ),
); );
} }
Widget planPopularityLeftItem() { Widget planPopularityView(List<PlansInfo> planInfo) {
return Container( return Container(
color: Colors.red, height: 265,
// height: 80, child: Container(
child: child: Column(children: <Widget>[
Expanded( titleView('111111'),
child: Stack( Row(children: <Widget>[
children: <Widget>[ Expanded(flex: 1, child: planPopularityLeftItem(planInfo[0])),
Positioned( Expanded(flex: 1, child: planPopularityRightItem(planInfo[1]))
right: 20, ])
top: 12, ])),
child: baseText('99%', 21, Color(0xffF25874),
bold: true)
),
Positioned(
right: 20,
top: 33,
// bottom: 12,
child: baseText('好评率', 12, Color(0xff666666),
bold: false),
),
Positioned(
right: 20,
top: 55,
// bottom: 12,
child: FiveStarView(3,5),
),
Positioned(
right: 20,
top: 98,
bottom: 12,
child: baseText('13679个', 21, Color(0xffF25874),
bold: true),
),
Positioned(
right: 20,
top: 112,
bottom: 12,
child: baseText('销量', 12, Color(0xff666666),
bold: false),
),
Positioned(
right: 20,
top: 132,
bottom: 12,
child: baseText('', 12, Color(0xff666666),
bold: false),
),
]
)
)
); );
} }
Widget planPopularityRightItem() {
return Container(
color: Colors.red,
// height: 80,
child:
Expanded(
child: Stack(
children: <Widget>[
Positioned(
left: 20,
top: 12,
child: baseText('99%', 21, Color(0xffF25874),
bold: true)
),
Positioned(
left: 20,
top: 33,
// bottom: 12,
child: baseText('好评率', 12, Color(0xff666666),
bold: false),
),
Positioned(
left: 20,
top: 55,
// bottom: 12,
child: FiveStarView(3,5),
),
Positioned(
left: 20,
top: 98,
bottom: 12,
child: baseText('13679个', 21, Color(0xffF25874),
bold: true),
),
Positioned( Widget planPopularityLeftItem(PlansInfo plan) {
left: 20, return Container(
top: 112, color: Colors.red,
bottom: 12, // height: 80,
child: baseText('销量', 12, Color(0xff666666), child: Expanded(
bold: false), child: Stack(children: <Widget>[
), Positioned(
right: 20,
top: 12,
child: baseText('99%', 21, Color(0xffF25874), bold: true)),
Positioned(
right: 20,
top: 33,
// bottom: 12,
child: baseText('好评率', 12, Color(0xff666666), bold: false),
),
Positioned(
right: 20,
top: 55,
// bottom: 12,
child: FiveStarView(3, 5),
),
Positioned(
right: 20,
top: 98,
bottom: 12,
child: baseText('13679个', 21, Color(0xffF25874), bold: true),
),
Positioned(
right: 20,
top: 112,
bottom: 12,
child: baseText('销量', 12, Color(0xff666666), bold: false),
),
Positioned(
right: 20,
top: 132,
bottom: 12,
child: baseText('', 12, Color(0xff666666), bold: false),
),
])));
}
Positioned( Widget planPopularityRightItem(PlansInfo plan) {
left: 20, return Container(
top: 132, color: Colors.red,
bottom: 12, // height: 80,
child: baseText('', 12, Color(0xff666666), child: Expanded(
bold: false), child: Stack(children: <Widget>[
), Positioned(
] left: 20,
top: 12,
) child: baseText('99%', 21, Color(0xffF25874), bold: true)),
) Positioned(
); left: 20,
} top: 33,
// bottom: 12,
child: baseText('好评率', 12, Color(0xff666666), bold: false),
),
Positioned(
left: 20,
top: 55,
// bottom: 12,
child: FiveStarView(3, 5),
),
Positioned(
left: 20,
top: 98,
bottom: 12,
child: baseText('13679个', 21, Color(0xffF25874), bold: true),
),
Positioned(
left: 20,
top: 112,
bottom: 12,
child: baseText('销量', 12, Color(0xff666666), bold: false),
),
Positioned(
left: 20,
top: 132,
bottom: 12,
child: baseText('', 12, Color(0xff666666), bold: false),
),
])));
}
Widget planNormalEffectiveAttrsView(Groups groups) { Widget planNormalEffectiveAttrsView(Groups groups) {
List<Widget> list = new List();
list.add(titleView(groups.groupName));
groups.plans.forEach((element) {
list.add(planBaseAttrsView(element));
});
return Container( return Container(
color: Colors.green, child: Column(
child: Column( mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: list
Expanded(
child: Stack( // <Widget>[
children: <Widget>[ // Expanded(
titleView(), // child: Stack(children: <Widget>[
Expanded ( // ,
child: Container( // Expanded(
margin: EdgeInsets.fromLTRB(0, 68, 0, 0), // child: Container(
child: // margin: EdgeInsets.fromLTRB(0, 68, 0, 0),
ListView.builder( // child:
itemBuilder: (c, index) { // ListView.builder(
return planBaseAttrsView(); // shrinkWrap: true,
}, // physics: NeverScrollableScrollPhysics(),
itemCount: 5, // itemBuilder: (c, index) {
) // return planBaseAttrsView(groups.plans);
) // },
) // itemCount: 5,
] // )))
) // ]))
) ));
]
)
);
} }
Widget planBaseAttrsView() { Widget planBaseAttrsView(Plans plans) {
return Container( return Container(
color: Colors.red, height: 56,
height: 80, child: Row(children: <Widget>[
child: Row( Expanded(flex: 1, child: planBaseAttrsLeftView(plans)),
children: <Widget>[ Expanded(flex: 1, child: planBaseAttrsRightView(plans))
Expanded( ]));
flex:1,
child: planBaseAttrsLeftView()
),
Expanded(
flex: 1,
child: planBaseAttrsRightView()
)
]
)
);
} }
Widget planBaseAttrsLeftView() { Widget planBaseAttrsLeftView(Plans plan) {
return Container( return Container(
color: Colors.red, height: 56,
height: 80, child: Stack(children: <Widget>[
child: Stack( Positioned(
children: <Widget>[ right: 20,
Positioned( top: 0,
right: 20, child: baseText(plan.attrs[0].attrValue, 14, Color(0xff3FB5AF),
top: 12, bold: true)),
child: baseText('嘻嘻嘻嘻嘻嘻', 14, Color(0xff3FB5AF), Positioned(
bold: true) top: 20,
), right: 20,
child: baseText(plan.attrs[0].attrName, 12, Color(0xff666666),
Positioned( bold: false),
right: 20, ),
// top: 12, ]));
bottom: 12, }
child: baseText('哈哈哈哈', 12, Color(0xff666666),
bold: false),
),
]
)
);
}
Widget planBaseAttrsRightView() {
return Container(
color: Colors.red,
height: 80,
child: Stack(
children: <Widget>[
Positioned(
left: 20,
top: 12,
child: baseText('嘻嘻嘻嘻嘻嘻', 14, Color(0xffF25874),
bold: true)
),
Positioned(
left: 20,
// top: 12,
bottom: 12,
child: baseText('哈哈哈哈', 12, Color(0xff666666),
bold: false),
),
] Widget planBaseAttrsRightView(Plans plan) {
return Container(
) height: 56,
); child: Stack(children: <Widget>[
} Positioned(
} left: 20,
\ No newline at end of file top: 0,
child: baseText(plan.attrs[0].attrValue, 14, Color(0xffF25874),
bold: true)),
Positioned(
left: 20,
top: 20,
child: baseText(plan.attrs[0].attrName, 12, Color(0xff666666),
bold: false),
),
]));
}
}
...@@ -22,8 +22,11 @@ class PlansCompareFeedItemView extends StatelessWidget { ...@@ -22,8 +22,11 @@ class PlansCompareFeedItemView extends StatelessWidget {
} }
getFirstLevelItem() { getFirstLevelItem() {
Container( return Container(
margin: EdgeInsets.all(4.0), width: double.maxFinite,
height: 90,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 15, right: 15, top: 20, bottom: 20),
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Radio( Radio(
...@@ -32,51 +35,56 @@ class PlansCompareFeedItemView extends StatelessWidget { ...@@ -32,51 +35,56 @@ class PlansCompareFeedItemView extends StatelessWidget {
onChanged: (value) { onChanged: (value) {
groupValue = value; groupValue = value;
}), }),
ClipRRect( Container(
borderRadius: BorderRadius.circular(2.0), margin: EdgeInsets.only(left: 15, right: 15),
child: Image.network( child: ClipRRect(
plan.projectImage, borderRadius: BorderRadius.circular(2.0),
width: 50, child: Image.network(
height: 50, plan.projectImage,
fit: BoxFit.fill, width: 50,
height: 50,
fit: BoxFit.fill,
),
), ),
), ),
Expanded( Container(
child: Container(
margin: EdgeInsets.only(left: 8.0),
height: 50, height: 50,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Row( Container(
children: <Widget>[ margin: EdgeInsets.only(top: 2, bottom: 5),
Text( child: Row(
plan.name, children: <Widget>[
style: TextStyle( Text(
fontWeight: FontWeight.bold, plan.name,
fontSize: 14, style: TextStyle(
color: Color(0xFF282828)), fontWeight: FontWeight.bold,
maxLines: 1, fontSize: 14,
), color: Color(0xFF282828)),
Text( maxLines: 1,
"好评率 ", ),
style: TextStyle(fontSize: 11, color: Color(0xFF282828)), Text(
maxLines: 1, "好评率 ",
), style:
Text( TextStyle(fontSize: 11, color: Color(0xFF282828)),
plan.positiveRate, maxLines: 1,
style: TextStyle( ),
fontWeight: FontWeight.bold, Text(
fontSize: 14, plan.positiveRate,
color: Color(0xFFFF5963)), style: TextStyle(
maxLines: 1, fontWeight: FontWeight.bold,
), fontSize: 14,
], color: Color(0xFFFF5963)),
maxLines: 1,
),
],
),
), ),
Row( Row(
children: <Widget>[ children: <Widget>[
Text( Text(
'¥${plan.minPrice}-${plan.maxPrice})', '¥${plan.minPrice}-${plan.maxPrice}',
style: TextStyle(fontSize: 13, color: Color(0xFFFF5963)), style: TextStyle(fontSize: 13, color: Color(0xFFFF5963)),
), ),
Text( Text(
...@@ -88,15 +96,18 @@ class PlansCompareFeedItemView extends StatelessWidget { ...@@ -88,15 +96,18 @@ class PlansCompareFeedItemView extends StatelessWidget {
) )
], ],
), ),
)) )
], ],
), ),
); );
} }
getSecondLevelItem() { getSecondLevelItem() {
Container( return Container(
margin: EdgeInsets.all(4.0), width: double.maxFinite,
height: 77,
alignment: Alignment.centerLeft,
margin: EdgeInsets.only(left: 15, right: 15),
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Radio( Radio(
...@@ -105,37 +116,44 @@ class PlansCompareFeedItemView extends StatelessWidget { ...@@ -105,37 +116,44 @@ class PlansCompareFeedItemView extends StatelessWidget {
onChanged: (value) { onChanged: (value) {
groupValue = value; groupValue = value;
}), }),
Expanded( Container(
child: Container( margin: EdgeInsets.only(left: 15.0),
margin: EdgeInsets.only(left: 8.0), height: 77,
height: 50, alignment: Alignment.centerLeft,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Text( Container(
plan.name, margin: EdgeInsets.only(top: 13.0, bottom: 12),
style: TextStyle( child: Text(
fontWeight: FontWeight.bold, plan.name,
fontSize: 14, style: TextStyle(
color: Color(0xFF282828)), fontWeight: FontWeight.bold,
maxLines: 1, fontSize: 14,
color: Color(0xFF282828)),
maxLines: 1,
),
), ),
Row( Row(
children: <Widget>[ children: <Widget>[
Text( Text(
'¥${plan.minPrice}-${plan.maxPrice})', '¥${plan.minPrice}-${plan.maxPrice}',
style: TextStyle(fontSize: 13, color: Color(0xFFFF5963)), style: TextStyle(fontSize: 13, color: Color(0xFFFF5963)),
), ),
Text( Container(
"指导价:¥${plan.guidePrice}", alignment: Alignment.centerRight,
style: TextStyle(fontSize: 11, color: Color(0xFF282828)), child: Text(
maxLines: 1, "指导价:¥${plan.guidePrice}",
) style:
TextStyle(fontSize: 11, color: Color(0xFF282828)),
maxLines: 1,
),
),
], ],
) )
], ],
), ),
)) )
], ],
), ),
); );
......
...@@ -4,6 +4,7 @@ import 'package:gm_flutter/ClueModel/server/api/ClueApi.serv.dart'; ...@@ -4,6 +4,7 @@ import 'package:gm_flutter/ClueModel/server/api/ClueApi.serv.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlansCompareFeed.dart'; import 'package:gm_flutter/ClueModel/server/entity/PlansCompareFeed.dart';
import 'package:gm_flutter/commonModel/net/DioUtil.dart'; import 'package:gm_flutter/commonModel/net/DioUtil.dart';
import 'package:gm_flutter/commonModel/rx/RxDispose.dart'; import 'package:gm_flutter/commonModel/rx/RxDispose.dart';
import 'package:gm_flutter/commonModel/util/PrintUtil.dart';
class PlansCompareFeedModel extends BaseModel { class PlansCompareFeedModel extends BaseModel {
LiveData<PlansCompareFeed> liveData = LiveData(); LiveData<PlansCompareFeed> liveData = LiveData();
...@@ -13,12 +14,12 @@ class PlansCompareFeedModel extends BaseModel { ...@@ -13,12 +14,12 @@ class PlansCompareFeedModel extends BaseModel {
ClueApiImpl.getInstance() ClueApiImpl.getInstance()
.getPlansCompareFeed(DioUtil.getInstance().getDio(), 123, 1) .getPlansCompareFeed(DioUtil.getInstance().getDio(), 123, 1)
.listen((event) { .listen((event) {
if (event.error == 0) { liveData.notifyView(event);
liveData.notifyView(event);
}
}) })
.addToDispose(rxDispose) .addToDispose(rxDispose)
.onError((err) {}); .onError((err) {
PrintUtil.printBug(err);
});
} }
@override @override
......
...@@ -38,9 +38,12 @@ class PlansCompareFeedState extends BaseState<PlansCompareFeedPage> { ...@@ -38,9 +38,12 @@ class PlansCompareFeedState extends BaseState<PlansCompareFeedPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: baseAppBar(
title: Text("方案对比"), title: "方案对比",
), centerTitle: true,
backClick: () {
Navigator.pop(context);
}),
body: Center( body: Center(
child: getBody(), child: getBody(),
), ),
...@@ -75,11 +78,19 @@ class PlansCompareFeedState extends BaseState<PlansCompareFeedPage> { ...@@ -75,11 +78,19 @@ class PlansCompareFeedState extends BaseState<PlansCompareFeedPage> {
getBody() { getBody() {
return StreamBuilder( return StreamBuilder(
stream: _model.liveData.stream, stream: _model.liveData.stream,
initialData: PlansCompareFeed(), initialData: _model.liveData.data ?? null,
builder: (c, data) { builder: (c, data) {
if (_model.liveData.data == null) {
return loadingItem();
}
PlansCompareFeed item = data.data; PlansCompareFeed item = data.data;
if (item == null || item.data == null || item.data.plans == null) { if (item == null || item.data == null || item.data.plans == null) {
return loadingItem(); return emptyItem(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height);
}
if (item.error != 0) {
return errorItem(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height, () {});
} }
return getList(item.data.plans); return getList(item.data.plans);
}, },
......
...@@ -18,13 +18,22 @@ class ProjectDetailsItemView extends StatelessWidget { ...@@ -18,13 +18,22 @@ class ProjectDetailsItemView extends StatelessWidget {
for (var item in listData.attrs) { for (var item in listData.attrs) {
tiles.add(getItem(item)); tiles.add(getItem(item));
} }
var row = Row( var column = Column(
children: <Widget>[ children: <Widget>[
Container( Container(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0, left: 20), padding: EdgeInsets.only(left: 15.0),
margin: EdgeInsets.only(bottom: 16.0),
alignment: Alignment.centerLeft,
width: double.maxFinite,
height: 55,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/bg_project_detail_item.png"),
fit: BoxFit.cover)),
child: Text( child: Text(
listData.name, listData.name,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold,
color: Color(0xFF000000), color: Color(0xFF000000),
fontSize: 15.0, fontSize: 15.0,
), ),
...@@ -36,30 +45,38 @@ class ProjectDetailsItemView extends StatelessWidget { ...@@ -36,30 +45,38 @@ class ProjectDetailsItemView extends StatelessWidget {
], ],
); );
return Container( return Container(
margin: EdgeInsets.only(bottom: 5, left: 20), margin: EdgeInsets.only(bottom: 5),
child: row, child: column,
); );
} }
getItem(Attrs attrs) { getItem(Attrs attrs) {
var row = Container( var row = Container(
margin: EdgeInsets.only(bottom: 25), width: double.maxFinite,
margin: EdgeInsets.only(bottom: 25, left: 15, right: 15),
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Text( Container(
attrs.attrName, margin: EdgeInsets.only(right: 25.0),
style: TextStyle( alignment: Alignment.centerLeft,
color: Color(0xFF999999), width: 78,
fontSize: 13.0, child: Text(
attrs.attrName,
style: TextStyle(
color: Color(0xFF999999),
fontSize: 13.0,
),
), ),
), ),
Text( Container(
attrs.attrValue, alignment: Alignment.centerLeft,
style: TextStyle( child: Text(
color: Color(0xFF282828), attrs.attrValue,
fontSize: 14.0, style: TextStyle(
color: Color(0xFF282828),
fontSize: 14.0,
),
), ),
maxLines: 1,
), ),
], ],
), ),
......
...@@ -20,15 +20,12 @@ class ProjectDetailsModel extends BaseModel { ...@@ -20,15 +20,12 @@ class ProjectDetailsModel extends BaseModel {
ClueApiImpl.getInstance() ClueApiImpl.getInstance()
.getProjectDetails(DioUtil.getInstance().getDio(), 123) .getProjectDetails(DioUtil.getInstance().getDio(), 123)
.listen((event) { .listen((event) {
print(event); liveData.notifyView(event);
if (event.error == 0) {
liveData.notifyView(event);
}
}) })
.addToDispose(rxDispose) .addToDispose(rxDispose)
.onError((err) { .onError((err) {
PrintUtil.printBug(err); PrintUtil.printBug(err);
}); });
} }
@override @override
......
...@@ -38,11 +38,12 @@ class ProjectDetailsState extends BaseState<ProjectDetailsPage> { ...@@ -38,11 +38,12 @@ class ProjectDetailsState extends BaseState<ProjectDetailsPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: baseAppBar(title: "项目说明", appBar: baseAppBar(
centerTitle: true, title: "项目说明",
backClick: (){ centerTitle: true,
Navigator.pop(context); backClick: () {
}), Navigator.pop(context);
}),
body: Center( body: Center(
child: getBody(), child: getBody(),
), ),
...@@ -52,11 +53,19 @@ class ProjectDetailsState extends BaseState<ProjectDetailsPage> { ...@@ -52,11 +53,19 @@ class ProjectDetailsState extends BaseState<ProjectDetailsPage> {
getBody() { getBody() {
return StreamBuilder( return StreamBuilder(
stream: _model.liveData.stream, stream: _model.liveData.stream,
initialData: ProjectDetailsItem(), initialData: _model.liveData.data ?? null,
builder: (c, data) { builder: (c, data) {
if (_model.liveData.data == null) {
return loadingItem();
}
ProjectDetailsItem item = data.data; ProjectDetailsItem item = data.data;
if (item == null || item.data == null || item.data.groups == null) { if (item == null || item.data == null || item.data.groups == null) {
return loadingItem(); return emptyItem(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height);
}
if (item.error != 0) {
return errorItem(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height, () {});
} }
return ListView.builder( return ListView.builder(
itemCount: item.data.groups.length, itemCount: item.data.groups.length,
......
...@@ -84,18 +84,9 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -84,18 +84,9 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
SliverPersistentHeader( SliverPersistentHeader(
pinned: true, pinned: true,
delegate: StickyTabBarDelegate( delegate: StickyTabBarDelegate(
child: TabBar( child: baseTabBar(tabController,
labelColor: Color(0xff282828), [baseTabBarItem("医院"), baseTabBarItem("医生")], (index) {},
labelStyle: scroll: false),
TextStyle(fontSize: 15.0, fontWeight: FontWeight.bold),
unselectedLabelColor: Color(0xffB5B5B5),
unselectedLabelStyle: TextStyle(fontSize: 15.0),
indicatorColor: Color(0xff4ABAB4),
indicatorWeight: 3.0,
indicatorSize: TabBarIndicatorSize.label,
indicatorPadding: EdgeInsets.only(left: 5.0, right: 5.0),
controller: this.tabController,
tabs: <Widget>[Tab(text: '医院'), Tab(text: '医生')]),
), ),
), ),
SliverFillRemaining(child: pages()) SliverFillRemaining(child: pages())
...@@ -517,7 +508,7 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -517,7 +508,7 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
} }
class StickyTabBarDelegate extends SliverPersistentHeaderDelegate { class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
final TabBar child; final Widget child;
StickyTabBarDelegate({@required this.child}); StickyTabBarDelegate({@required this.child});
...@@ -528,10 +519,10 @@ class StickyTabBarDelegate extends SliverPersistentHeaderDelegate { ...@@ -528,10 +519,10 @@ class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
} }
@override @override
double get maxExtent => this.child.preferredSize.height; double get maxExtent => 40;
@override @override
double get minExtent => this.child.preferredSize.height; double get minExtent => 40;
@override @override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) { bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
......
...@@ -20,6 +20,7 @@ class PlanModel extends BaseModel { ...@@ -20,6 +20,7 @@ class PlanModel extends BaseModel {
LiveData<List<double>> posLive = new LiveData(); LiveData<List<double>> posLive = new LiveData();
LiveData<List<double>> backLive = new LiveData(); LiveData<List<double>> backLive = new LiveData();
LiveData<List<Ranks>> picLive = LiveData(); LiveData<List<Ranks>> picLive = LiveData();
LiveData<bool> showTab = LiveData();
LiveData<int> stateLive = LiveData(); LiveData<int> stateLive = LiveData();
double menuBottom; double menuBottom;
...@@ -108,6 +109,7 @@ class PlanModel extends BaseModel { ...@@ -108,6 +109,7 @@ class PlanModel extends BaseModel {
posLive.dispost(); posLive.dispost();
backLive.dispost(); backLive.dispost();
feedsLive.dispost(); feedsLive.dispost();
showTab.dispost();
} }
void backProgress(double pro, int index) { void backProgress(double pro, int index) {
......
...@@ -9,6 +9,7 @@ import 'dart:ui'; ...@@ -9,6 +9,7 @@ import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/page/levelTwo/LevelTwoPage.dart';
import 'package:gm_flutter/ClueModel/page/plan/FilterView.dart'; import 'package:gm_flutter/ClueModel/page/plan/FilterView.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanBar.dart'; import 'package:gm_flutter/ClueModel/page/plan/PlanBar.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanItem.dart'; import 'package:gm_flutter/ClueModel/page/plan/PlanItem.dart';
...@@ -33,7 +34,7 @@ class PlanPage extends StatefulWidget { ...@@ -33,7 +34,7 @@ class PlanPage extends StatefulWidget {
State<StatefulWidget> createState() => PlanState(); State<StatefulWidget> createState() => PlanState();
} }
class PlanState extends BaseState<PlanPage> { class PlanState extends BaseState<PlanPage> with TickerProviderStateMixin {
PlanModel _model = PlanModel(); PlanModel _model = PlanModel();
TextEditingController _editingController = TextEditingController(); TextEditingController _editingController = TextEditingController();
FocusNode focusNode = FocusNode(); FocusNode focusNode = FocusNode();
...@@ -53,8 +54,8 @@ class PlanState extends BaseState<PlanPage> { ...@@ -53,8 +54,8 @@ class PlanState extends BaseState<PlanPage> {
_model.init(); _model.init();
planBarView = planBarView =
PlanBarView(_model.managerLive, clickIndex, hideAllMenuListener); PlanBarView(_model.managerLive, clickIndex, hideAllMenuListener);
planList.add(towPic()); planList.add(towPic().toActive());
planList.add(planBar()); planList.add(planBar().toActive());
planList.add(pages()); planList.add(pages());
} }
...@@ -110,7 +111,9 @@ class PlanState extends BaseState<PlanPage> { ...@@ -110,7 +111,9 @@ class PlanState extends BaseState<PlanPage> {
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Container( Container(
height: data.data[1] - 45, height: data.data[1] - 45 < 0
? 0
: data.data[1] - 45,
color: Colors.transparent, color: Colors.transparent,
), ),
Container( Container(
...@@ -215,6 +218,19 @@ class PlanState extends BaseState<PlanPage> { ...@@ -215,6 +218,19 @@ class PlanState extends BaseState<PlanPage> {
}, },
); );
}), }),
StreamBuilder<bool>(
stream: _model.showTab.stream,
initialData: _model.showTab.data ?? false,
builder: (c, data) {
return Visibility(
visible: data.data,
child: Container(
color: Colors.white,
child: planBarView,
),
);
},
)
], ],
), ),
) )
...@@ -303,9 +319,7 @@ class PlanState extends BaseState<PlanPage> { ...@@ -303,9 +319,7 @@ class PlanState extends BaseState<PlanPage> {
focusNode: focusNode, focusNode: focusNode,
autocorrect: false, autocorrect: false,
autofocus: false, autofocus: false,
textInputAction: Platform.isAndroid textInputAction: TextInputAction.search,
? TextInputAction.newline
: TextInputAction.send,
controller: _editingController, controller: _editingController,
minLines: null, minLines: null,
onEditingComplete: () {}, onEditingComplete: () {},
...@@ -316,27 +330,35 @@ class PlanState extends BaseState<PlanPage> { ...@@ -316,27 +330,35 @@ class PlanState extends BaseState<PlanPage> {
} }
Widget child() { Widget child() {
return baseRefreshView( return NotificationListener(
refreshController, onNotification: (scrollNotification) {
() { if (scrollNotification is ScrollUpdateNotification &&
_model.refreshFeed(true); scrollNotification.metrics.axisDirection.index == 2) {
_onScroll(scrollNotification.metrics.pixels);
}
return false;
}, },
Container( child: baseRefreshView(
width: 0, refreshController,
height: 0, () {
), _model.refreshFeed(true);
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return planList[index];
}, },
childCount: planList.length, Container(
), width: 0,
), height: 0,
onLoading: () { ),
_model.loadMore(); SliverList(
}, delegate: SliverChildBuilderDelegate(
pullUp: true); (BuildContext context, int index) {
return planList[index];
},
childCount: planList.length,
),
),
onLoading: () {
_model.loadMore();
},
pullUp: true));
} }
Widget towPic() { Widget towPic() {
...@@ -410,8 +432,14 @@ class PlanState extends BaseState<PlanPage> { ...@@ -410,8 +432,14 @@ class PlanState extends BaseState<PlanPage> {
} }
void clickIndex(int index) { void clickIndex(int index) {
var topPos = PosUtil.findPos(globalKey);
double bottom = double bottom =
WidgetUtil.buttonLeftMenuPosition(globalKey.currentContext).top - 86; // WidgetUtil.buttonLeftMenuPosition(globalKey.currentContext)?.top ??
topPos == null ? 0.0 : topPos.dy + 45 - 86;
if (bottom < 45) {
bottom = 45;
}
_model.menuBottom = bottom; _model.menuBottom = bottom;
if (_model.menuIndex == index || _model.menuIndex == -1) { if (_model.menuIndex == index || _model.menuIndex == -1) {
_model.needChangBack = true; _model.needChangBack = true;
...@@ -449,6 +477,7 @@ class PlanState extends BaseState<PlanPage> { ...@@ -449,6 +477,7 @@ class PlanState extends BaseState<PlanPage> {
height = max(_model.feedDatas.length * 100.0, height); height = max(_model.feedDatas.length * 100.0, height);
} }
return Container( return Container(
color: Color(0xffF7F6FA),
width: double.maxFinite, width: double.maxFinite,
height: height, height: height,
child: ListView.builder( child: ListView.builder(
...@@ -479,4 +508,27 @@ class PlanState extends BaseState<PlanPage> { ...@@ -479,4 +508,27 @@ class PlanState extends BaseState<PlanPage> {
}, },
); );
} }
void _onScroll(double offset) {
var topPos = PosUtil.findPos(globalKey);
if (topPos != null) {
if (topPos.dy > 86) {
_model.showTab.notifyView(false);
} else {
_model.showTab.notifyView(true);
}
}
// if (topPos != null && topPos.dy < 0) {
// double dy = -topPos.dy;
// if (dy < 20) {
// dy = 0;
// }
// double alpha = dy / 112;
// if (alpha < 0) {
// alpha = 0;
// } else if (alpha > 1) {
// alpha = 1;
// }
// _model.showTab.notifyView(alpha);
}
} }
/*
* @author lsy
* @date 2020/7/2
**/
import 'package:flutter_common/commonModel/live/BaseModel.dart';
import 'package:flutter_common/commonModel/live/LiveData.dart';
class TopModel extends BaseModel {
int tabIndex = 0;
List<String> tabs = ["全部", "眼部", "自体脂肪", "轮廓骨骼"];
@override
void dispose() {}
void selectTab(int index) {
if (tabIndex == index) {
return;
}
tabIndex = index;
}
}
/*
* @author lsy
* @date 2020/7/2
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/page/levelTwo/LevelTwoPage.dart';
import 'package:gm_flutter/ClueModel/page/top/TopModel.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/base/BaseState.dart';
import 'package:gm_flutter/commonModel/view/baseTabIndicator.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class TopPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => TopPageState();
}
class TopPageState extends BaseState<TopPage> with TickerProviderStateMixin {
RefreshController refreshController = RefreshController();
TabController tabController;
TopModel _model = TopModel();
@override
void initState() {
tabController = TabController(length: 4, vsync: this);
super.initState();
}
@override
void dispose() {
refreshController.dispose();
super.dispose();
}
@override
Widget buildItem(BuildContext context) {
return Scaffold(
body: home(),
);
}
Widget home() {
return baseRefreshView(refreshController, () {}, null, null,
customScrollView: CustomScrollView(slivers: <Widget>[
SliverAppBar(
pinned: true,
elevation: 0,
expandedHeight: 0,
flexibleSpace: FlexibleSpaceBar(title: Text('二级方案')),
),
SliverToBoxAdapter(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
height: 50,
color: Colors.pink,
)
],
)),
SliverPersistentHeader(
pinned: true,
delegate: StickyTabBarDelegate(
child: Container(
height: 40,
color: Colors.white,
child: baseTabBar(tabController, getTabs(), (index) {
_model.selectTab(index);
}),
)),
),
SliverFillRemaining(
child: TabBarView(controller: tabController, children: <Widget>[
Container(
color: Colors.red,
),
Container(
color: Colors.red,
),
Container(
color: Colors.red,
),
Container(
color: Colors.blue,
)
]))
]));
}
List<Widget> getTabs() {
List<Widget> list = [];
for (int i = 0; i < _model.tabs.length; i++) {
list.add(baseTabBarItem(_model.tabs[i],
leftPadding: i == 0 ? 24 : 28,
rightPadding: i == _model.tabs.length - 1 ? 24 : 28));
}
return list;
}
}
...@@ -19,11 +19,11 @@ import 'package:gm_flutter/commonModel/net/Responce/SimpleResponce.dart'; ...@@ -19,11 +19,11 @@ import 'package:gm_flutter/commonModel/net/Responce/SimpleResponce.dart';
@ServiceCenter() @ServiceCenter()
abstract class ClueApi { abstract class ClueApi {
@Get("/api/janus/plans/plan_detail") @Get("/api/janus/plans/plan_detail")
ProjectDetailsItem getProjectDetails(@Query("plan_id") int plan_id); ProjectDetailsItem getProjectDetails(@Query("plan_id") double plan_id);
@Get("/api/janus/plans/compare_feed") @Get("/api/janus/plans/compare_feed")
PlansCompareFeed getPlansCompareFeed( PlansCompareFeed getPlansCompareFeed(
@Query("plan_id") int plan_id, @Query("plan_type") int plan_type); @Query("plan_id") double plan_id, @Query("plan_type") double plan_type);
@Get("api/janus/plans/plan_feed") @Get("api/janus/plans/plan_feed")
LevelOneFeedList getLevelOneList(@Query("plan_id") int plan_id, LevelOneFeedList getLevelOneList(@Query("plan_id") int plan_id,
......
...@@ -40,7 +40,7 @@ class ClueApiImpl { ...@@ -40,7 +40,7 @@ class ClueApiImpl {
return _instance; return _instance;
} }
Stream<ProjectDetailsItem> getProjectDetails(Dio _dio, int plan_id) { Stream<ProjectDetailsItem> getProjectDetails(Dio _dio, double plan_id) {
return Stream.fromFuture(get(_dio, '/api/janus/plans/plan_detail', data: { return Stream.fromFuture(get(_dio, '/api/janus/plans/plan_detail', data: {
'plan_id': plan_id, 'plan_id': plan_id,
})).flatMap((value) { })).flatMap((value) {
...@@ -55,7 +55,7 @@ class ClueApiImpl { ...@@ -55,7 +55,7 @@ class ClueApiImpl {
} }
Stream<PlansCompareFeed> getPlansCompareFeed( Stream<PlansCompareFeed> getPlansCompareFeed(
Dio _dio, int plan_id, int plan_type) { Dio _dio, double plan_id, double plan_type) {
return Stream.fromFuture(get(_dio, '/api/janus/plans/compare_feed', data: { return Stream.fromFuture(get(_dio, '/api/janus/plans/compare_feed', data: {
'plan_id': plan_id, 'plan_id': plan_id,
'plan_type': plan_type, 'plan_type': plan_type,
......
...@@ -3,7 +3,7 @@ class PlansCompareFeed { ...@@ -3,7 +3,7 @@ class PlansCompareFeed {
String message; String message;
String extra; String extra;
String errorExtra; String errorExtra;
String userType; UserType userType;
Data data; Data data;
PlansCompareFeed( PlansCompareFeed(
...@@ -19,7 +19,9 @@ class PlansCompareFeed { ...@@ -19,7 +19,9 @@ class PlansCompareFeed {
message = json['message']; message = json['message'];
extra = json['extra']; extra = json['extra'];
errorExtra = json['error_extra']; errorExtra = json['error_extra'];
userType = json['user_type']; userType = json['user_type'] != null
? new UserType.fromJson(json['user_type'])
: null;
data = json['data'] != null ? new Data.fromJson(json['data']) : null; data = json['data'] != null ? new Data.fromJson(json['data']) : null;
} }
...@@ -29,7 +31,9 @@ class PlansCompareFeed { ...@@ -29,7 +31,9 @@ class PlansCompareFeed {
data['message'] = this.message; data['message'] = this.message;
data['extra'] = this.extra; data['extra'] = this.extra;
data['error_extra'] = this.errorExtra; data['error_extra'] = this.errorExtra;
data['user_type'] = this.userType; if (this.userType != null) {
data['user_type'] = this.userType.toJson();
}
if (this.data != null) { if (this.data != null) {
data['data'] = this.data.toJson(); data['data'] = this.data.toJson();
} }
...@@ -37,6 +41,17 @@ class PlansCompareFeed { ...@@ -37,6 +41,17 @@ class PlansCompareFeed {
} }
} }
class UserType {
UserType();
UserType.fromJson(Map<String, dynamic> json) {}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
return data;
}
}
class Data { class Data {
List<Plans> plans; List<Plans> plans;
......
...@@ -3,7 +3,7 @@ class ProjectDetailsItem { ...@@ -3,7 +3,7 @@ class ProjectDetailsItem {
String message; String message;
String extra; String extra;
String errorExtra; String errorExtra;
String userType; UserType userType;
Data data; Data data;
ProjectDetailsItem( ProjectDetailsItem(
...@@ -19,7 +19,9 @@ class ProjectDetailsItem { ...@@ -19,7 +19,9 @@ class ProjectDetailsItem {
message = json['message']; message = json['message'];
extra = json['extra']; extra = json['extra'];
errorExtra = json['error_extra']; errorExtra = json['error_extra'];
userType = json['user_type']; userType = json['user_type'] != null
? new UserType.fromJson(json['user_type'])
: null;
data = json['data'] != null ? new Data.fromJson(json['data']) : null; data = json['data'] != null ? new Data.fromJson(json['data']) : null;
} }
...@@ -29,7 +31,9 @@ class ProjectDetailsItem { ...@@ -29,7 +31,9 @@ class ProjectDetailsItem {
data['message'] = this.message; data['message'] = this.message;
data['extra'] = this.extra; data['extra'] = this.extra;
data['error_extra'] = this.errorExtra; data['error_extra'] = this.errorExtra;
data['user_type'] = this.userType; if (this.userType != null) {
data['user_type'] = this.userType.toJson();
}
if (this.data != null) { if (this.data != null) {
data['data'] = this.data.toJson(); data['data'] = this.data.toJson();
} }
...@@ -37,6 +41,17 @@ class ProjectDetailsItem { ...@@ -37,6 +41,17 @@ class ProjectDetailsItem {
} }
} }
class UserType {
UserType();
UserType.fromJson(Map<String, dynamic> json) {}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
return data;
}
}
class Data { class Data {
int id; int id;
String name; String name;
......
...@@ -7,8 +7,9 @@ import 'package:flutter/cupertino.dart'; ...@@ -7,8 +7,9 @@ import 'package:flutter/cupertino.dart';
class FiveStarView extends StatelessWidget { class FiveStarView extends StatelessWidget {
final int allStarCount; final int allStarCount;
final int lightStarCount; final int lightStarCount;
String starAssets;
FiveStarView(this.lightStarCount, this.allStarCount); FiveStarView(this.lightStarCount, this.allStarCount, {this.starAssets});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -18,7 +19,7 @@ class FiveStarView extends StatelessWidget { ...@@ -18,7 +19,7 @@ class FiveStarView extends StatelessWidget {
list.add(Container( list.add(Container(
height: 13, height: 13,
width: 13, width: 13,
child: Image.asset("assets/sel_star.png"), child: Image.asset(starAssets ?? "assets/sel_star.png"),
)); ));
if (i != 0 && i != allStarCount - 1) { if (i != 0 && i != allStarCount - 1) {
list.add(Container( list.add(Container(
......
...@@ -45,6 +45,14 @@ class TestState extends BaseState<TestPage> { ...@@ -45,6 +45,14 @@ class TestState extends BaseState<TestPage> {
JumpUtil.jumpToPageRight( JumpUtil.jumpToPageRight(
context, RouterCenterImpl().findClueRouter().getProjectDetailsPage()); context, RouterCenterImpl().findClueRouter().getProjectDetailsPage());
})); }));
list.add(listItem("方案对比", () {
JumpUtil.jumpToPageRight(context, RouterCenterImpl().findClueRouter().getPlansCompareFeed());
}));
list.add(listItem("榜单", () {
JumpUtil.jumpToPageRight(context, RouterCenterImpl().findClueRouter().getTopPage());
}));
return list; return list;
} }
......
...@@ -13,6 +13,7 @@ import 'package:flutter_svg/svg.dart'; ...@@ -13,6 +13,7 @@ import 'package:flutter_svg/svg.dart';
import 'package:gm_flutter/commonModel/GMBase.dart'; import 'package:gm_flutter/commonModel/GMBase.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart'; import 'package:gm_flutter/commonModel/util/DartUtil.dart';
import 'package:gm_flutter/commonModel/view/ImagesAnimation.dart'; import 'package:gm_flutter/commonModel/view/ImagesAnimation.dart';
import 'package:gm_flutter/commonModel/view/baseTabIndicator.dart';
import 'package:lottie/lottie.dart'; import 'package:lottie/lottie.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
...@@ -396,3 +397,36 @@ Widget emptyItem(double width, double height, {String detail}) { ...@@ -396,3 +397,36 @@ Widget emptyItem(double width, double height, {String detail}) {
), ),
); );
} }
Widget baseTabBar(
TabController controller, List<Widget> list, Function(int index) clickItem,
{BaseIndicator baseIndicator, double fontSize, Color color, bool scroll}) {
return TabBar(
onTap: clickItem,
controller: controller,
indicatorSize: TabBarIndicatorSize.tab,
isScrollable: scroll ?? true,
unselectedLabelColor: color ?? Color(0xffB5B5B5),
labelColor: color ?? Color(0xff282828),
labelStyle: TextStyle(fontSize: fontSize ?? 16),
unselectedLabelStyle: TextStyle(fontSize: fontSize ?? 16),
labelPadding: EdgeInsets.only(),
indicator: baseIndicator ?? BaseIndicator(),
tabs: list,
);
}
Widget baseTabBarItem(String text,
{double leftPadding, double rightPadding, double wantWidth}) {
leftPadding = leftPadding ?? 28.0;
rightPadding = rightPadding ?? 28.0;
double width = leftPadding + text.length * 16.0 + rightPadding;
return Container(
height: 40,
width: wantWidth ?? width,
alignment: Alignment.center,
child: Tab(
text: text,
),
);
}
...@@ -19,7 +19,13 @@ class WidgetUtil { ...@@ -19,7 +19,13 @@ class WidgetUtil {
} }
static RelativeRect buttonLeftMenuPosition(BuildContext c) { static RelativeRect buttonLeftMenuPosition(BuildContext c) {
if (c == null) {
return null;
}
final RenderBox bar = c.findRenderObject(); final RenderBox bar = c.findRenderObject();
if (Overlay.of(c).context == null) {
return null;
}
final RenderBox overlay = Overlay.of(c).context.findRenderObject(); final RenderBox overlay = Overlay.of(c).context.findRenderObject();
final RelativeRect position = RelativeRect.fromRect( final RelativeRect position = RelativeRect.fromRect(
Rect.fromPoints( Rect.fromPoints(
......
library md2_tab_indicator;
import 'package:flutter/widgets.dart';
class BaseIndicator extends Decoration {
double indicatorHeight;
Color indicatorColor;
double indicatorRadius;
double indicatorWidth;
double indicatorPaddingBottom;
BaseIndicator(
{this.indicatorHeight,
this.indicatorColor,
this.indicatorRadius,
this.indicatorWidth,
this.indicatorPaddingBottom}) {
indicatorHeight = indicatorHeight ?? 3.0;
indicatorColor = indicatorColor ?? Color(0xff3FB5AF);
indicatorRadius = indicatorRadius ?? 1.5;
indicatorWidth = indicatorWidth ?? 22.0;
indicatorPaddingBottom = indicatorPaddingBottom ?? 6.0;
}
@override
_MD2Painter createBoxPainter([VoidCallback onChanged]) {
return new _MD2Painter(this, onChanged);
}
}
class _MD2Painter extends BoxPainter {
final BaseIndicator decoration;
_MD2Painter(this.decoration, VoidCallback onChanged)
: assert(decoration != null),
super(onChanged);
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
assert(configuration != null);
assert(configuration.size != null);
Rect rect = Offset(
offset.dx +
configuration.size.width / 2 -
decoration.indicatorWidth / 2,
(configuration.size.height -
decoration.indicatorHeight -
decoration.indicatorPaddingBottom)) &
Size(decoration.indicatorWidth, decoration.indicatorHeight);
final Paint paint = Paint();
paint.color = decoration.indicatorColor;
paint.style = PaintingStyle.fill;
double radius = decoration.indicatorRadius;
canvas.drawRRect(
RRect.fromRectAndCorners(rect,
topRight: Radius.circular(radius),
topLeft: Radius.circular(radius),
bottomLeft: Radius.circular(radius),
bottomRight: Radius.circular(radius)),
paint);
}
}
...@@ -78,7 +78,10 @@ class MyApp extends State<MyAppWidget> { ...@@ -78,7 +78,10 @@ class MyApp extends State<MyAppWidget> {
theme: ThemeData( theme: ThemeData(
primaryColor: Colors.white, primaryColor: Colors.white,
cursorColor: Color(0xff20BDBB), cursorColor: Color(0xff20BDBB),
highlightColor:Colors.transparent,
splashColor:Colors.transparent,
canvasColor: Colors.white), canvasColor: Colors.white),
builder: FlutterBoost.init(postPush: _onRoutePushed), builder: FlutterBoost.init(postPush: _onRoutePushed),
home: isDebug home: isDebug
? RouterCenterImpl().findMainRouter().getTestPage() ? RouterCenterImpl().findMainRouter().getTestPage()
......
...@@ -7,14 +7,14 @@ packages: ...@@ -7,14 +7,14 @@ packages:
name: _fe_analyzer_shared name: _fe_analyzer_shared
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "4.0.0" version: "5.0.0"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.39.10" version: "0.39.11"
app_settings: app_settings:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -453,7 +453,7 @@ packages: ...@@ -453,7 +453,7 @@ packages:
name: path_provider_linux name: path_provider_linux
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.0.1+1" version: "0.0.1+2"
path_provider_macos: path_provider_macos:
dependency: transitive dependency: transitive
description: description:
...@@ -731,7 +731,7 @@ packages: ...@@ -731,7 +731,7 @@ packages:
name: url_launcher_web name: url_launcher_web
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.1.1+6" version: "0.1.2"
uuid: uuid:
dependency: transitive dependency: transitive
description: description:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment