1.最外层套脚手架控件:Scaffold,设置背景为透明或半透明。目的是将弹出键盘是的高度计算调整交给Scaffold。(直接用SingleChildScrollView仍然会出现布局溢出)
2.使用SingleChildScrollView包裹弹窗布局。
示例:
import 'package:jade/bean/createExpParam/BuyChargeDetail.dart';
import 'package:jade/configs/PathConfig.dart';
import 'package:jade/customWidget/CusBehavior.dart';
import 'package:jade/utils/JadeColors.dart';
import 'package:jade/utils/Utils.dart';
import 'package:util/easy_loading_util.dart';
import 'package:util/navigator_util.dart';
import 'package:util/number_text_input_formatter.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';class CellPriceInfo{int monthNum; //月数double price;//价格double originPrice;//原价
// double oneMonthPrice;//单月价格bool isSelect; //是否选中TextEditingController priceController;TextEditingController originPriceController;CellPriceInfo({this.monthNum,this.price,this.originPrice,this.isSelect = false,this.priceController,this.originPriceController}){this.priceController = priceController ?? TextEditingController();this.originPriceController = originPriceController ?? TextEditingController();}
}class FillInCellPriceDialog extends StatefulWidget{final int showNum;final Function sureCallBack;final List<BuyChargeDetail> viewedPriceInfoList;const FillInCellPriceDialog({this.sureCallBack,this.showNum,this.viewedPriceInfoList});State<StatefulWidget> createState() {// TODO: implement createStatereturn _FillInCellPriceDialog();}
}class _FillInCellPriceDialog extends State<FillInCellPriceDialog>{List<CellPriceInfo> _priceInfoList = []; //绘制ui的数组List<BuyChargeDetail> _buyChargeDetailList = [];//从弹窗返出去的数组void initState() {// TODO: implement initStatesuper.initState();_priceInfoList = [CellPriceInfo(monthNum: 10007),CellPriceInfo(monthNum: 10014),CellPriceInfo(monthNum: 1),CellPriceInfo(monthNum: 3),CellPriceInfo(monthNum: 6),CellPriceInfo(monthNum: 12)];if(widget.viewedPriceInfoList != null && widget.viewedPriceInfoList.isNotEmpty){for (var viewedPriceInfo in widget.viewedPriceInfoList) {for (var priceInfo in _priceInfoList) {if(viewedPriceInfo.monthNum == priceInfo.monthNum){priceInfo.priceController.text = '${viewedPriceInfo.price}';priceInfo.originPriceController.text = '${viewedPriceInfo.originPrice ?? ''}';priceInfo.isSelect = true;}}}}}void dispose() {// TODO: implement disposeif(_priceInfoList.isNotEmpty){_priceInfoList.forEach((element) {element.priceController.dispose();element.originPriceController.dispose();});}super.dispose();}Widget build(BuildContext context) {// TODO: implement buildreturn Scaffold(backgroundColor: Colors.transparent,body:ScrollConfiguration(behavior: CusBehavior(),child: SingleChildScrollView(child: Container(alignment: Alignment.center,margin: EdgeInsets.only(top: Utils().screenWidth(context) * 0.18),child: UnconstrainedBox(child: Container(alignment: Alignment.center,width: Utils().screenWidth(context) * 0.76,padding: EdgeInsets.only(top: 40.w, bottom: 30.w),decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10)),child: Column(mainAxisSize: MainAxisSize.min,crossAxisAlignment: CrossAxisAlignment.start,children: [Container(padding: EdgeInsets.only(left: 30.w, right: 40.w,),child: Text(widget.showNum == null ? '展位(格口)价格设置' : '${widget.showNum}号展位(格口)价格设置',style: TextStyle(color: JadeColors.grey_2,fontSize: 30.sp,fontWeight: FontWeight.w600)),),Container(padding: EdgeInsets.only(left: 30.w, right: 40.w,),child: Text('需设置原价与活动价(即实际售卖价格)',style: TextStyle(color: JadeColors.grey,fontSize: 24.sp,fontWeight: FontWeight.w600)),),Container(height: 1,color: JadeColors.grey_5,margin: EdgeInsets.only(top: 30.w,bottom: 30.w)),_listView(),SizedBox(height: 40.w),_btnView()],))),)),));}_listView(){return ListView.separated(itemBuilder: (context, index) {return _itemView(index);},shrinkWrap: true,physics: const NeverScrollableScrollPhysics(),separatorBuilder: (context,index) =>Container(height: 30.w,),itemCount: _priceInfoList.length);}_itemView(int index){return Container(padding: EdgeInsets.only(left: 30.w, right: 40.w),child: Row(children: [GestureDetector(child: Container(color: Colors.white,padding: EdgeInsets.all(5),child: Image.asset(_priceInfoList[index].isSelect ? PathConfig.iconSelectBlue2 : PathConfig.iconUnselect, width: 34.w,height: 34.w),),onTap: (){setState(() {_priceInfoList[index].isSelect = !_priceInfoList[index].isSelect;});},),SizedBox(width: Utils().monthNumToDayNum(_priceInfoList[index].monthNum) > 99 ? 24.w : Utils().monthNumToDayNum(_priceInfoList[index].monthNum) < 10 ? 50.w :40.w),Text('${Utils().monthNumToDayNum(_priceInfoList[index].monthNum)}天:',style: TextStyle(color: JadeColors.grey_3,fontSize: 28.sp)),Expanded(child: Column(children: [Container(width: double.infinity,height: 54.w,padding: EdgeInsets.symmetric(horizontal: 20.w),alignment: Alignment.center,decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),border: Border.all(width: 1.w,color: JadeColors.grey)),child: TextField(enabled: _priceInfoList[index].isSelect,textAlign: TextAlign.start,controller: _priceInfoList[index].priceController,style: TextStyle(fontSize: 24.sp, color: JadeColors.grey_2),keyboardType: TextInputType.number,textInputAction: TextInputAction.done,inputFormatters: [NumberTextInputFormatter(2),FilteringTextInputFormatter(RegExp("[0-9.]"), allow: true),],maxLines: 1,maxLength: 40,decoration: InputDecoration(filled: true,fillColor: Colors.white,isCollapsed: true,isDense: true,contentPadding: EdgeInsets.zero,hintText: '请输入活动价(必填)',hintStyle: TextStyle(fontSize: 24.sp,color: JadeColors.grey,),disabledBorder: OutlineInputBorder(borderSide: BorderSide.none,borderRadius: BorderRadius.circular(8.w)),enabledBorder: OutlineInputBorder(borderSide: BorderSide.none),focusedBorder: OutlineInputBorder(borderSide: BorderSide.none),border: OutlineInputBorder(borderSide: BorderSide.none),counterText: ''),onChanged: (value) {if(value.isNotEmpty){double _parsedDouble = double.tryParse(value);if(_parsedDouble == null || _parsedDouble < 1){esLoadingToast('活动价格不能低于1元');}}},cursorColor: JadeColors.grey,)),SizedBox(height: 10.w),Container(width: double.infinity,height: 54.w,padding: EdgeInsets.symmetric(horizontal: 20.w),alignment: Alignment.center,decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),border: Border.all(width: 1.w,color: JadeColors.grey)),child: TextField(enabled: _priceInfoList[index].isSelect,textAlign: TextAlign.start,controller: _priceInfoList[index].originPriceController,style: TextStyle(fontSize: 24.sp, color: JadeColors.grey_2),keyboardType: TextInputType.number,textInputAction: TextInputAction.done,inputFormatters: [NumberTextInputFormatter(2),FilteringTextInputFormatter(RegExp("[0-9.]"), allow: true),],maxLines: 1,maxLength: 40,decoration: InputDecoration(filled: true,fillColor: Colors.white,isCollapsed: true,isDense: true,contentPadding: EdgeInsets.zero,hintText: '请输入原价',hintStyle: TextStyle(fontSize: 24.sp,color: JadeColors.grey,),disabledBorder: OutlineInputBorder(borderSide: BorderSide.none,borderRadius: BorderRadius.circular(8.w)),enabledBorder: OutlineInputBorder(borderSide: BorderSide.none),focusedBorder: OutlineInputBorder(borderSide: BorderSide.none),border: OutlineInputBorder(borderSide: BorderSide.none),counterText: ''),onChanged: (value) {},cursorColor: JadeColors.grey,)),],))],));}_btnView(){return Row(mainAxisAlignment: MainAxisAlignment.end,children: [GestureDetector(child: Container(height: 44.w,padding: EdgeInsets.symmetric(horizontal: 40.w),margin: EdgeInsets.only(right: 20.w),alignment: Alignment.center,decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(20),border: Border.all(color: JadeColors.blue_2,width: 1.w)),child: Text('取消',style: TextStyle(color: JadeColors.blue_2,fontSize: 26.sp)),),onTap: (){NavigatorUtil.pop();}),GestureDetector(child: Container(height: 44.w,padding: EdgeInsets.symmetric(horizontal: 40.w),margin: EdgeInsets.only(right: 40.w),alignment: Alignment.center,decoration: BoxDecoration(color: JadeColors.blue_2,borderRadius: BorderRadius.circular(20)),child: Text('确定',style: TextStyle(color: Colors.white,fontSize: 26.sp)),),onTap: () async {print('_getPriceData= ${_getPriceData()}');if(_getPriceData() == null || !_getPriceData()){return;}if(widget.sureCallBack != null){widget.sureCallBack(_buyChargeDetailList);}NavigatorUtil.pop();},)],);}//要返出去的参数_getPriceData(){_buyChargeDetailList.clear();bool _canCallback = false;for(var element in _priceInfoList){if(element.isSelect){String _price = element.priceController.text.trim();String _originPrice = element.originPriceController.text.trim();double _parsedPriceDouble = double.tryParse(_price);double _parsedOriginPriceDouble = double.tryParse(_originPrice);if(_price.isEmpty){esLoadingToast('请输入${Utils().monthNumToDayNum(element.monthNum)}天活动价');_canCallback = false;return;}else if(_price.isNotEmpty && _parsedPriceDouble == null || _parsedPriceDouble < 1){esLoadingToast('${Utils().monthNumToDayNum(element.monthNum)}天活动价不能低于1元');_canCallback = false;return;}else{_canCallback = true;}if(_parsedOriginPriceDouble != null && _parsedOriginPriceDouble < 1){esLoadingToast('${Utils().monthNumToDayNum(element.monthNum)}天原价不能低于1元');_canCallback = false;return;}BuyChargeDetail _buyChargeDetail = BuyChargeDetail(monthNum: element.monthNum,price: double.parse(_price),originPrice: _originPrice.isNotEmpty ? double.parse(_originPrice) : null,);_buyChargeDetailList.add(_buyChargeDetail);}}return _canCallback;}}