I am having an issue where the keyboard covers and hides the bottom sheet.
I tried a number of solutions but nothing seems to work. I am not too sure what is causing the problem. My guess is that it has something to do with either nested Scaffold and/or using bottom sheet in TabBarView.
Any help would be greatly appreciated.
I tried to include as much detail as possible. If you need anything else, please let me know.
Code below:
DetailsPage.dart
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
key: _scaffoldKey,
appBar: AppBar(
centerTitle: true,
title: UtilWidget.getLogo(),
bottom: TabBar(
labelColor: Colors.deepPurpleAccent,
unselectedLabelColor: Colors.white,
indicatorSize: TabBarIndicatorSize.label,
indicator: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10)),
color: Colors.white),
tabs: [
UtilWidget.addTab('Details'),
UtilWidget.addTab('Procedures'),
],
),
),
body: TabBarView(
children: <Widget>[
EditServiceFragment(contractorServiceId: widget.contractorServiceId),
ServiceProceduresFragment(contractorServiceId: widget.contractorServiceId)
],
),
)
);
}
ServiceProceduresFragment.dart
@override
Widget build(BuildContext context) {
return Scaffold(
primary: false,
resizeToAvoidBottomInset: true,
key: _scaffoldKey,
body: _buildPage(),
floatingActionButton: new FloatingActionButton.extended(
onPressed: () {
_addProcedureBottomSheet(context);
},
label: Text('Add Procedure'),
icon: new Icon(Icons.add),
),
);
}
Widget _buildPage() {
return FutureBuilder(
future: _loadedContractorService,
builder: (BuildContext context, AsyncSnapshot<ContractorService> serviceRes) {
if(serviceRes.hasError) {
print('Error while loading Asset - EditService');
print(serviceRes.error);
return UtilWidget.pageLoadError(
"SERVICE PROCEDURES",
"An Error has occurred",
"Got an error getting Contractor Service from the API."
);
}
if (serviceRes.connectionState == ConnectionState.waiting)
return UtilWidget.progressIndicator();
ContractorService loadedService = serviceRes.data;
List<Procedure> procedures = loadedService.procedures;
if(procedures.length == 0)
return UtilWidget.emptyListView('SERVICE PROCEDURES', 'No procedures were found. Add one.');
return SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
itemCount: procedures.length + 1,
itemBuilder: (context, index) {
if(index == 0){
return UtilWidget.pageHeader('SERVICE PROCEDURES');
}
int listIndex = index - 1;
Procedure procedure = procedures[listIndex];
return Card(
elevation: 2,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
margin: EdgeInsets.only(top: 10, bottom: 10, left: 20, right: 20),
child: Theme(
data: ThemeData().copyWith(
dividerColor: Colors.transparent,
accentColor: Colors.deepPurpleAccent
),
child: ExpansionTile(
title: ListTile(
title: Text(
procedure.name,
style: TextStyle(fontWeight: FontWeight.bold)
),
subtitle: Text(
'Requirements: ' +
procedure.requirements.length.toString()
),
),
childrenPadding: EdgeInsets.only(left: 20, right: 20),
children: [
UtilWidget.addRowWithText('Notes', FontWeight.bold),
UtilWidget.addRowWithText(procedure.notes, FontWeight.normal),
_deleteProcedureBtn(procedure.id),
Padding(
padding: const EdgeInsets.only(top: 10),
child: UtilWidget.addRowWithText('Requirements', FontWeight.bold),
),
for(var req in procedure.requirements)
UtilWidget.addRowWithText(req.name, FontWeight.normal)
,
_addRequirementBtn(procedure.id)
]
)
)
);
}
)
);
}
);
}
void _addProcedureBottomSheet(BuildContext context) {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext bc) {
return SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.only(
top: 10, left:15, right:15,
bottom: MediaQuery.of(context).viewInsets.bottom
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Center(
child: Text(
'Add Procedure to Service',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18
),
),
),
_addProcedureForm()
],
),
)
);
}
);
}
Form _addProcedureForm() {
return Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
validator: (value) {
if(value.isEmpty) {
return 'Service name is required.';
}
return null;
},
controller: _name,
decoration: InputDecoration(
labelText: 'Name',
hintText: "Specific/applicable procedure",
icon: Icon(Icons.edit, color: Colors.deepPurple)
)
),
TextFormField(
validator: (value) {
if(value.isEmpty) {
return 'Service description is required.';
}
return null;
},
maxLines: null,
keyboardType: TextInputType.multiline,
controller: _notes,
decoration: InputDecoration(
labelText: 'Description',
hintText: "Applicable procedure description.",
icon: Icon(Icons.notes, color: Colors.deepPurple)
)
),
Container(
margin: const EdgeInsets.only(top: 20.0, bottom: 10),
child: SizedBox(
width: double.maxFinite,
child: RaisedButton(
color: Colors.deepPurple,
textColor: Colors.white,
padding: EdgeInsets.all(5),
child: Text('Save Procedure',
style: TextStyle(fontSize: 15)
),
onPressed: () {
if(_formKey.currentState.validate()) {
_submitProcedureForm();
}
},
),
),
)
],
),
);
}
Widget _addRequirementBtn(int procedureId) {
return Padding(
padding: const EdgeInsets.only(top: 10.0, bottom: 10),
child: RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
color: Colors.deepPurple,
textColor: Colors.white,
child: Text('Add Requirement',
style: TextStyle(fontSize: 14)
),
onPressed: () {
_addProcedureRequirementBottomSheet(procedureId, context);
}
)
);
}
Outputs

