Flutter的自定义控件比安卓要简单的多。
在Android里,自定控件需要继承某个View,然后写一大堆代码。而Flutter的自定义控件就是Widget的嵌套与组合,Flutter app本身就是一堆Widget的嵌套。感觉就是写Android的自定义控件需要费一番功夫,而Flutter的自定义控件不知不觉就完成了。
如果要做一个对话框,是怎样的呢?
–代码中包含业务逻辑,用到了Bloc和Dio,这个懒得删除了–
首先在需要使用对话框的地方,直接这样:
CheckInDialog就是我们要show出来的对话框
showDialog(
context: context,
builder: (BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<CommonBloc>(
create: (context) => CommonBloc(),
),
BlocProvider<BoxBloc>(
create: (context) => BoxBloc(),
),
],
child: CheckInDialog(
orderItem: widget.orderItem,
onCheckInSuccess: () {
widget.parent.onRefresh();
}),
);
});
然后定义对话框的内容
虽然也有继承Dialog,但child里的CheckInView,就是一个普通的widget嵌套,跟普通的页面编写一模一样。
import 'package:flutter/material.dart';
import 'package:keyboxfluttermodule/src/constant/constant.dart';
import 'package:keyboxfluttermodule/src/model/yes_or_no_item.dart';
import 'package:keyboxfluttermodule/src/widget/upload_peer_dialog.dart';
import 'package:keyvox_base/common/process.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:keyvoxbiz/biz/common/blocs/common_bloc.dart';
import 'package:keyvoxbiz/biz/common/models/kyc_info.dart';
import 'package:keyvoxbiz/biz/keybox/models/order_item.dart';
import 'package:keyvoxbiz/biz/keybox/blocs/box_bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:keyvox_base/keyvox_base.dart';
import 'package:keyvox_base/common/bclbutton.dart';
import 'package:minefluttermodule/src/pages/kyc_page.dart';
class CheckInDialog extends Dialog {
OrderItem orderItem;
Function onCheckInSuccess;
CheckInDialog({this.orderItem, this.onCheckInSuccess});
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<BoxBloc>(
create: (context) => BoxBloc(),
),
],
child: CheckInView(onCheckInSuccess: onCheckInSuccess, orderItem: this.orderItem),
);
}
}
class CheckInView extends StatefulWidget {
OrderItem orderItem;
Function onCheckInSuccess;
CheckInView({this.orderItem, this.onCheckInSuccess});
@override
State<StatefulWidget> createState() {
return CheckInWidget();
}
}
class CheckInWidget extends State<CheckInView> {
BoxBloc boxBloc;
CommonBloc commonBloc;
String _peopleNum;
YesOrNo _yesOrNo;
KYCInfoModel kycInfo;
var _peopleNumList = <String>['1', '2', '3', '4'];
var _yesOrNoList = <YesOrNo>[
YesOrNo('yes'.tr(), true),
YesOrNo('not'.tr(), false),
];
bool isConfirmEnable = true;
@override
void initState() {
super.initState();
boxBloc = BlocProvider.of<BoxBloc>(context);
commonBloc = BlocProvider.of<CommonBloc>(context);
}
void queryKyc() {
commonBloc.add(KycCheckEvent());
}
@override
Widget build(BuildContext context) {
if (_yesOrNo == null) {
_yesOrNo = _yesOrNoList[0];
}
if (_peopleNum == null) {
_peopleNum = '1';
}
return MultiBlocListener(
listeners: [
BlocListener<CommonBloc, CommonState>(
listener: (context, state) {
if (state is KycInfoState) {
kycInfo = state.kycInfo;
//verifyLevel 本人认证级别 0需要jumio认证(默认),1简易认证,2不需要认证。
//selfVerify 是否需要本人认证,0-否 1-是; null不知道 暂时认为是不需要吧
if (widget.orderItem?.orderDetail?.verifyLevel != null && widget.orderItem?.orderDetail?.verifyLevel == 2 ||
(widget.orderItem?.orderDetail?.verifyLevel == null && (widget.orderItem?.orderDetail?.selfVerify == null || widget.orderItem?.orderDetail?.selfVerify == 0))) {
//不需要认证
checkIn();
} else {
//需要认证
int status = kycInfo.status;
switch (status) {
case KeyboxConstant.SUCCESS_KYC: //认证成功
checkIn();
break;
case KeyboxConstant.INPREVIEW_KYC: //正在认证中
BCLButtonKeeper.instance.state.stop();
KeyvoxBase.showToast("kyc_in_review_tips".tr());
break;
case KeyboxConstant.NO_KYC: //没有实名认证,先去实名认证,因为认证需要时间,所以没必要onActivityResult
case KeyboxConstant.FAIL_KYC:
showNoKycDialog();
break;
}
}
}
},
),
BlocListener<BoxBloc, BoxState>(
listener: (context, state) {
print("============================= BlocListener state is:" + state.toString());
if (state is BoxSuccess) {
if (state.eventName == 'CheckInEvent') {
BCLButtonKeeper.instance.state.stop();
Navigator.of(context).pop();
KeyvoxBase.showToast("check_in_success".tr());
widget.onCheckInSuccess();
}
} else if (state is BoxFailure) {
BCLButtonKeeper.instance.state.stop();
}
},
),
],
child: BlocBuilder<CommonBloc, CommonState>(builder: (context, state) {
return BlocBuilder<BoxBloc, BoxState>(condition: (preState, state) {
print("============================= policy state is:" + state.toString());
if (state is BoxFailure) {
return false;
} else {
return true;
}
}, builder: (context, state) {
return Material(
type: MaterialType.transparency,
child: Center(
child: Container(
padding: EdgeInsets.only(left: 15, right: 15),
height: 400,
width: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Process.theme.sub1Color,
),
child: Column(
children: [
Align(
alignment: Alignment.topRight,
child: IconButton(
iconSize: 18,
icon: Icon(IconData(0xe68b, fontFamily: 'iconfont')),
onPressed: () {
Navigator.of(context).pop();
},
),
),
Text("select_guest_amount_title".tr(), style: TextStyle(color: Process.theme.mainTextColor, fontSize: 18)),
'housing' == widget.orderItem.orderDetail?.businessType
? Container(
//只有住房才显示人数
margin: EdgeInsets.only(top: 20),
child: PeopleNumView(this),
)
: Container(
margin: EdgeInsets.only(
top: 20,
),
),
Expanded(
child: YesOrNoView(this),
),
Container(
margin: EdgeInsets.only(
top: 15,
),
height: 42,
width: 200,
child: BCLButton(
text: "check_in".tr(),
style: TextStyle(color: Process.theme.sub1TextColor),
color: Process.theme.mainColor,
onPressed: isConfirmEnable
? () {
queryKyc();
}
: null),
),
Container(
margin: EdgeInsets.only(top: 15, bottom: 15),
height: 42,
width: 200,
child: RaisedButton(
color: Process.theme.subColor,
child: Text(
"cancel".tr(),
style: TextStyle(color: Process.theme.mainTextColor),
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
],
),
),
),
);
});
}),
);
}
///需要kyc,弹出框
void showNoKycDialog() {
BCLButtonKeeper.instance.state.stop();
showDialog(
context: context,
builder: (BuildContext dialogContext) {
return AlertDialog(
title: Text('no_kyc_title'.tr()),
content: Text('start_kyc_hint'.tr()),
actions: [
FlatButton(
child: new Text('no'.tr()),
onPressed: () {
Navigator.of(dialogContext).pop();
},
),
FlatButton(
child: new Text('yes'.tr()),
onPressed: () {
Navigator.of(dialogContext).pop();
Navigator.of(context).push(MaterialPageRoute(
settings: RouteSettings(name: "kyc"),
builder: (BuildContext context) {
return Center(
child: BlocProvider(
create: (context) {
return BoxBloc();
},
child: KycPage(/*onKycSubmited:(){
Navigator.of(context).pop();
}*/),
),
);
}));
// Routers.router.navigateTo(context, '/kyc', transition: TransitionType.cupertino);
},
),
],
);
});
}
void checkIn() {
//如果只选择客人人数大于1,需要填写其他人信息,否则直接提交checkIn,如果已经提交过客人信息了,也直接checkIn
int peopleNumInt = int.parse(this._peopleNum);
if (peopleNumInt > 1) {
BCLButtonKeeper.instance.state.stop();
showDialog(
context: context,
builder: (BuildContext context) {
return UploadPeerDialog(
peerNum: peopleNumInt - 1,
orderItem: widget.orderItem,
onCheckInSuccess: () {
widget.onCheckInSuccess();
Navigator.of(context).pop();
}); //同伴数量,要减去自己
});
} else {
boxBloc.add(
CheckInEvent(customerNum: peopleNumInt, orderId: widget.orderItem.orderId, orgId: widget.orderItem.orgId, unitId: widget.orderItem.unitId));
isConfirmEnable = false;
setState(() {});
}
}
}
class YesOrNoView extends StatefulWidget {
CheckInWidget checkInWidget;
YesOrNoView(this.checkInWidget);
@override
State<StatefulWidget> createState() {
return YesOrNoWidget();
}
}
class YesOrNoWidget extends State<YesOrNoView> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
"guest_is_oneself".tr(),
style: TextStyle(color: Process.theme.mainTextColor, fontSize: 13),
),
),
DropdownButton<YesOrNo>(
icon: Icon(IconData(0xe615 , fontFamily: 'iconfont')),
value: widget.checkInWidget._yesOrNo,
elevation: 16,
isExpanded: true,
style: TextStyle(
color: Process.theme.mainTextColor,
),
onChanged: (YesOrNo yesOrNo) {
setState(() {
widget.checkInWidget._yesOrNo = yesOrNo;
});
},
items: widget.checkInWidget._yesOrNoList.map<DropdownMenuItem<YesOrNo>>((YesOrNo yesOrNo) {
return DropdownMenuItem<YesOrNo>(
value: yesOrNo,
child: Text(yesOrNo.text, style: (TextStyle(color: Process.theme.mainTextColor))),
);
}).toList(),
),
],
);
}
}
class PeopleNumView extends StatefulWidget {
CheckInWidget checkInWidget;
PeopleNumView(this.checkInWidget);
@override
State<StatefulWidget> createState() {
return PeopleNumWidget();
}
}
class PeopleNumWidget extends State<PeopleNumView> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Text(
"guest_amount".tr(),
style: TextStyle(color: Process.theme.mainTextColor, fontSize: 13),
),
),
DropdownButton<String>(
icon: Icon(IconData(0xe615 , fontFamily: 'iconfont')),
value: widget.checkInWidget._peopleNum,
elevation: 16,
isExpanded: true,
style: TextStyle(
color: Process.theme.mainTextColor,
),
onChanged: (String text) {
setState(() {
widget.checkInWidget._peopleNum = text;
});
},
items: widget.checkInWidget._peopleNumList.map<DropdownMenuItem<String>>((String text) {
return DropdownMenuItem<String>(
value: text,
child: Text(text, style: (TextStyle(color: Process.theme.mainTextColor))),
);
}).toList(),
),
],
);
}
}
如果觉得写的不错,可以请我喝杯咖啡
|