【发布时间】:2020-11-14 21:19:06
【问题描述】:
我有一个用于从图库上传图像的块。然后我有一个TextField 我在其中输入文本。最后是另一个我有按钮的区域。该按钮用于将数据提交到服务器(图像和文本)。我的问题是启用按钮。我的启用代码是:
class ObservationPage extends StatefulWidget {
@override
_ObservationPageState createState() => _ObservationPageState();
}
class _ObservationPageState extends State<ObservationPage> {
List<File> files = [];
TextEditingController _descriptionController = TextEditingController();
TextEditingController _taskNameController = TextEditingController();
String taskName;
List<String> _selectedUsers = [];
bool _enabled = false;
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
BlocProvider.of<ImageBloc>(context).add(DeleteAllImages(files: files));
return true;
},
child: Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
centerTitle: true,
iconTheme: IconThemeData(
color: RioColours.darkGrey,
),
backgroundColor: Colors.grey[200],
elevation: 0,
title: Text('Observation',style:TextStyle(color: Colors.black))
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(left: 20.0, right: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20,),
Column(children: [
AutoSizeText(
'Make an Observation and assign to a colleague ',
maxLines: 1,
style: RioTextStyle.auditQuestion(context),
),
SizedBox(height: 20,),
AttachPhoto(),
SizedBox(height: 20,),
BlocBuilder<ImageBloc, ImageState>(builder: (context, state) {
if (state is ImageInitial) {
return Container();
}
if (state is ImageLoadInProgress) {
return CircularProgressIndicator();
}
if (state is ImageLoadSuccess) {
//print(state.files);
files = state.files;
return SizedBox(
//height: MediaQuery.of(context).size.height*.5,
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: state.files.length,
itemBuilder: (context, item) {
return Padding(
padding: const EdgeInsets.only(bottom:10.0),
child: ImageContainer(context: context, file: state.files[item]),
);
}),
);
}
if (state is NoImages) {
return Container();
}
if (state is ImageLoadFailure) {
return Container();
}
return Container();
})
]),
Text(
'Notes',
style: RioTextStyle.auditHeaders(context),
),
SizedBox(
height:10
),
SizedBox(height: 140,
child: TextField(
textInputAction: TextInputAction.next,
keyboardType: TextInputType.multiline,
maxLines: 5,
controller: _descriptionController,
onChanged: (String value) {
setState(() {});
},
style: TextStyle(fontSize: 16.0, height: 2.0, color: Colors.black),
decoration: new InputDecoration(
hintStyle: RioTextStyle.hintText(context),
fillColor: Colors.white,
filled: true,
focusedBorder: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey[300]),
),
hintText: "Enter your notes here"
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * .04,
),
Text(
'Task Name',
style: RioTextStyle.auditHeaders(context),
),
SizedBox(
height: 10
),
TextField(
controller: _taskNameController,
onChanged: (String value) {
setState(() {});
},
textInputAction: TextInputAction.next,
style: TextStyle(fontSize: 16.0, height: 2.0, color: Colors.black),
decoration: new InputDecoration(
fillColor: Colors.white,
filled: true,
focusedBorder: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey[300]),
),
hintStyle: RioTextStyle.hintText(context),
hintText: "Enter your task name here"
),
),
SizedBox(
height: 20
),
SizedBox(
height: 20
),
BlocBuilder<ObservationBloc, ObservationState>(builder: (context, state) {
if (state is UsersLoadInProgress) {
return Center(child: CircularProgressIndicator());
}
if (state is UsersLoadSuccess) {
final users = state.users;
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(
'Assign to',
style: RioTextStyle.auditHeaders(context),
),
SizedBox(
height: MediaQuery.of(context).size.height * .02,
),
MultiSelectDialogField(
buttonIcon: Icon(Icons.arrow_drop_down,color: Colors.grey,),
chipDisplay: MultiSelectChipDisplay(
chipColor: Colors.white,
textStyle: TextStyle(color: Colors.black),
),
onConfirm: (results) {
_selectedUsers.clear();
for (User user in results) {
_selectedUsers.add(user.id);
setState(() {
_enabled = true;
});
}
// _selectedUsers = results;
print(_selectedUsers);
},
items: users.map((user) => MultiSelectItem<User>(user, user.first_name)).toList(),
title: Text(
'Assign Owners',
style: TextStyle(color: RioColours.splashBlue),
),
cancelText: Text(
"CANCEL",
style: TextStyle(color: RioColours.splashBlue),
),
confirmText: Text(
"ASSIGN",
style: TextStyle(color: RioColours.splashBlue),
),
buttonText: Text(
"Choose Owners",
style: RioTextStyle.dropDownHint(context),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * .05,
),
]);
}
if (state is UserLoadFailure) {
return Text('error');
}
return Container();
}),
BlocConsumer<ButtonBloc, ButtonState>(listener: (context, state) {
if (state is UploadFailure) {
RioHelpers.showFailureFlushBar(context, 'Error Uploading');
Navigator.of(context).pop();
}
if (state is UpLoadSuccess) {
_submit();
}
}, builder: (context, state) {
if (state is Loading) {
return Center(child: CircularProgressIndicator());
}
if (state is ButtonInitial) {
print(_enabled);
return SizedBox(
height: MediaQuery.of(context).size.height * .07,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: (_descriptionController.text.isNotEmpty && _taskNameController.text.isNotEmpty && _enabled) ? () => callupLoad() : null,
color: RioColours.splashBlue,
child: Text(
'Submit',
style: RioTextStyle.buttonText(context),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
);
}
if (state is UpLoadSuccess) {
BlocProvider.of<ImageBloc>(context).add(DeleteAllImages(files: files));
return SizedBox(
height: MediaQuery.of(context).size.height * .07,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: (_descriptionController.text.isNotEmpty && _taskNameController.text.isNotEmpty && _enabled) ? () => callupLoad() : null,
color: RioColours.splashBlue,
child: Text(
'Submit',
style: RioTextStyle.buttonText(context),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
);
}
if (state is UploadFailure) {
return SizedBox(
height: MediaQuery.of(context).size.height * .07,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
onPressed: () {},
//onPressed: (controller.text.isNotEmpty && _enabled) ? () => callupLoad() : null,
color: RioColours.splashBlue,
child: Text(
'Submit',
style: RioTextStyle.buttonText(context),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
);
}
return Container(
color: Colors.yellow,
height: 10,
);
}),
SizedBox(
height: MediaQuery.of(context).size.height * .12,
),
],
),
),
)),
);
}
callupLoad() {
BlocProvider.of<ButtonBloc>(context).add(UploadTaskRequest(files: files, notes: _descriptionController.text, taskName: _taskNameController.text, owners: _selectedUsers));
}
_submit() async {
print('called called called called called ');
RioHelpers.showSuccessFlushBar(context, 'Observation recorded');
BlocProvider.of<ImageBloc>(context).add(DeleteAllImages(files: files));
await Future.delayed(Duration(seconds: 3));
Navigator.of(context).pop();
}
@override
void initState() {
BlocProvider.of<ObservationBloc>(context).add(RequestUsers());
super.initState();
print("init calledx");
_enabled = false;
}
}
所以_controller 非常适合启用/禁用按钮。但是 _enabled 这是一个布尔状态变量是我的问题。在我的blocbuilder 中,当图像上传成功时,我将状态更新为_enabled= true。但是,这对启用按钮没有任何影响。我还使用bloclistener 更新了状态变量,但这也不起作用。
当我从图库上传图片时如何触发按钮启用
【问题讨论】:
-
我不确定我是否理解您的问题。
_controller.text.isNotEmpty && && _enabled是什么?它无法编译。 -
抱歉应该是
(_controller.text.isNotEmpty && _enabled)这是我用来启用/禁用按钮的条件 -
它不起作用的原因有很多。也许状态类的 hashcode/equals 实现不正确。也许您的小部件层次结构有问题,等等。提供更多信息,以便可以提供帮助。提供的代码很难理解。看起来没什么问题。
-
这里是完整的代码。如果你发现任何东西,请告诉我!
标签: flutter flutter-bloc