Flutter 将值传递给上一个小部件
我有一个简单的表格,里面有一个圆形的相机,当按下这个按钮时,可以选择从画廊或相机拍照。为了使我的小部件更紧凑,我将它分离到一些文件中Flutter 将值传递给上一个小部件,flutter,Flutter,我有一个简单的表格,里面有一个圆形的相机,当按下这个按钮时,可以选择从画廊或相机拍照。为了使我的小部件更紧凑,我将它分离到一些文件中 FormDoSensScreen(它是主屏幕) DosenImagePicker(它是唯一的循环雷达) ModalBottomSheet PickImage(用于显示ModalBottomSheet) 问题是,我不知道如何将值从ModalBottomSheetPickImage传递到FormDosenScreen。因为来自ModalBottomSheetPickI
类FormDoSensScreen扩展StatefulWidget{
静态常量routeName='/formdosen screen';
@凌驾
_FormDoSensCrenstate createState()=>\u FormDoSensCrenstate();
}
类_formDoSensCrenstate扩展状态{
字符串选择文件;
@凌驾
小部件构建(构建上下文){
final detectKeyboardOpen=MediaQuery.of(context).viewInsets.bottom;
打印(“触发器”);
返回脚手架(
appBar:appBar(
标题:对,
标题:文本(“Tambah Dosen”),
行动:[
弹出菜单按钮(
itemBuilder:(\u)=>[
PopupMenuItem(
child:Text('Tambah Pelajaran'),
值:“添加_pelajaran”,
),
],
onSelected:(字符串值){
开关(值){
“add_pelajaran”一案:
Navigator.of(context.pushNamed)(FormPelajaranScreen.routeNamed);
打破
违约:
}
},
)
],
),
主体:堆栈(
fit:StackFit.expand,
儿童:[
SingleChildScrollView(
子:列(
mainAxisSize:mainAxisSize.min,
crossAxisAlignment:crossAxisAlignment.stretch,
儿童:[
尺寸箱(高度:20),
DosenImagePicker(onPickedImage:(文件)=>selectedFile=file),
尺寸箱(高度:20),
卡片(
边距:常量边集。对称(水平:15,垂直:10),
孩子:填充(
填充:常数边集。全部(20),
子:列(
crossAxisAlignment:crossAxisAlignment.stretch,
儿童:[
TextFormFieldCustom(
onSaved:(值){},
标签文字:“Nama Dosen”,
),
尺寸箱(高度:20),
TextFormFieldCustom(
onSaved:(值){},
前缀:图标(Icons.email),
labelText:“电子邮件地址”,
键盘类型:TextInputType.emailAddress,
),
尺寸箱(高度:20),
TextFormFieldCustom(
onSaved:(值){},
键盘类型:TextInputType.number,
输入格式化程序:[
//InputNumberFormat(),
WhiteListingPutFormatter.digitsOnly
],
前缀:图标(图标。本地电话),
labelText:“Telepon Dosen”,
),
],
),
),
),
SizedBox(高度:kToolbarHeight),
],
),
),
定位(
孩子:可见度(
可见:detectKeyboardOpen>0?假:真,
孩子:升起按钮(
已按下:(){
打印(所选文件);
},
MaterialTargetSize:MaterialTargetSize.shrinkWrap,
颜色:colorPallete.primaryColor,
子:文本(
"辛潘",,
样式:TextStyle(fontWeight:fontWeight.bold,fontFamily:AppConfig.headerFont),
),
形状:圆形RectangleBorder(borderRadius:borderRadius.circular(20)),
textTheme:buttonexttheme.primary,
),
),
底部:KToolbar高度/2,
左:尺寸。宽度(上下文)/15,
右:尺寸。宽度(上下文)/15,
)
],
),
);
}
}
第二个小部件
类DosenImagePicker扩展StatefulWidget{
最终函数(字符串文件)onPickedImage;
DosenImagePicker({@required this.onPickedImage});
@凌驾
DosenImagePickerState createState()=>DosenImagePickerState();
}
类DosenImagePickerState扩展了状态{
字符串选择图像;
@凌驾
小部件构建(构建上下文){
返回对齐(
对齐:对齐.center,
孩子:InkWell(
onTap:()异步{
等待展示ModalBottomSheet(
上下文:上下文,
生成器:(上下文)=>ModalBottomSheetPickImage(
onPickedImage:(文件){
设置状态(){
选择edimage=file;
widget.onPickedImage(选择eImage);
打印(“Hellooo dosen图像选择器$SelecteImage”);
});
},
),
);
},
孩子:圆环星(
前底色:colorPallete.black,
backgroundImage:SelecteImage==null?null:MemoryImage(base64.decode(SelecteImage)),
半径:尺寸。宽度(上下文)/6,
美国银行
class FormDosenScreen extends StatefulWidget {
static const routeNamed = '/formdosen-screen';
@override
_FormDosenScreenState createState() => _FormDosenScreenState();
}
class _FormDosenScreenState extends State<FormDosenScreen> {
String selectedFile;
@override
Widget build(BuildContext context) {
final detectKeyboardOpen = MediaQuery.of(context).viewInsets.bottom;
print('trigger');
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Tambah Dosen'),
actions: <Widget>[
PopupMenuButton(
itemBuilder: (_) => [
PopupMenuItem(
child: Text('Tambah Pelajaran'),
value: 'add_pelajaran',
),
],
onSelected: (String value) {
switch (value) {
case 'add_pelajaran':
Navigator.of(context).pushNamed(FormPelajaranScreen.routeNamed);
break;
default:
}
},
)
],
),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(height: 20),
DosenImagePicker(onPickedImage: (file) => selectedFile = file),
SizedBox(height: 20),
Card(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextFormFieldCustom(
onSaved: (value) {},
labelText: 'Nama Dosen',
),
SizedBox(height: 20),
TextFormFieldCustom(
onSaved: (value) {},
prefixIcon: Icon(Icons.email),
labelText: 'Email Dosen',
keyboardType: TextInputType.emailAddress,
),
SizedBox(height: 20),
TextFormFieldCustom(
onSaved: (value) {},
keyboardType: TextInputType.number,
inputFormatter: [
// InputNumberFormat(),
WhitelistingTextInputFormatter.digitsOnly
],
prefixIcon: Icon(Icons.local_phone),
labelText: 'Telepon Dosen',
),
],
),
),
),
SizedBox(height: kToolbarHeight),
],
),
),
Positioned(
child: Visibility(
visible: detectKeyboardOpen > 0 ? false : true,
child: RaisedButton(
onPressed: () {
print(selectedFile);
},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
color: colorPallete.primaryColor,
child: Text(
'SIMPAN',
style: TextStyle(fontWeight: FontWeight.bold, fontFamily: AppConfig.headerFont),
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
textTheme: ButtonTextTheme.primary,
),
),
bottom: kToolbarHeight / 2,
left: sizes.width(context) / 15,
right: sizes.width(context) / 15,
)
],
),
);
}
}
class DosenImagePicker extends StatefulWidget {
final Function(String file) onPickedImage;
DosenImagePicker({@required this.onPickedImage});
@override
DosenImagePickerState createState() => DosenImagePickerState();
}
class DosenImagePickerState extends State<DosenImagePicker> {
String selectedImage;
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.center,
child: InkWell(
onTap: () async {
await showModalBottomSheet(
context: context,
builder: (context) => ModalBottomSheetPickImage(
onPickedImage: (file) {
setState(() {
selectedImage = file;
widget.onPickedImage(selectedImage);
print('Hellooo dosen image picker $selectedImage');
});
},
),
);
},
child: CircleAvatar(
foregroundColor: colorPallete.black,
backgroundImage: selectedImage == null ? null : MemoryImage(base64.decode(selectedImage)),
radius: sizes.width(context) / 6,
backgroundColor: colorPallete.accentColor,
child: selectedImage == null ? Text('Pilih Gambar') : SizedBox(),
),
),
);
}
}
class ModalBottomSheetPickImage extends StatelessWidget {
final Function(String file) onPickedImage;
ModalBottomSheetPickImage({@required this.onPickedImage});
@override
Widget build(BuildContext context) {
return SizedBox(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Wrap(
alignment: WrapAlignment.spaceEvenly,
children: <Widget>[
InkWell(
onTap: () async {
final String resultBase64 =
await commonFunction.pickImage(quality: 80, returnFile: ReturnFile.BASE64);
onPickedImage(resultBase64);
},
child: CircleAvatar(
foregroundColor: colorPallete.white,
backgroundColor: colorPallete.green,
child: Icon(Icons.camera_alt),
),
),
InkWell(
onTap: () async {
final String resultBase64 =
await commonFunction.pickImage(returnFile: ReturnFile.BASE64, isCamera: false);
onPickedImage(resultBase64);
},
child: CircleAvatar(
foregroundColor: colorPallete.white,
backgroundColor: colorPallete.blue,
child: Icon(Icons.photo_library),
),
),
],
),
),
);
}
}
class ImageModel extends ChangeNotifier {
String _base64Image;
get base64Image => _base64Image;
set base64Image(String base64Image) {
_base64Image = base64Image;
notifyListeners();
}
}
final model=Provider.of<ImageModel>(context,listen:false);
String image=model.base64Image; //get data
model.base64Image=resultBase64; //set your image data after you used ImagePicker
@override
Widget build(BuildContext context) {
//other widgets
Selector<ImageModel, String>(
selector: (_, model) => model.base64Image,
builder: (_, image, __) {
return Text(image);
},
);
}
)
}