I need a popup menu or any other way to implement layout like this in flutter. I have tried to implememnt it in popup view but I wasn't successful. Please help me with this problem.
Here is the code I have tried, implementing it using any other method also will be fine. This code gives error no material widget found, if it can be fixed it'll also be helpful for me.
void showFilter() {
showGeneralDialog(
barrierLabel: "Barrier",
barrierDismissible: true,
barrierColor: Colors.black.withOpacity(0.5),
transitionDuration: Duration(milliseconds: 700),
context: context,
pageBuilder: (_, __, ___) {
return Align(
alignment: Alignment.center,
child: Container(
height: 300,
child: SizedBox.expand(
child:Column(
children: <Widget>[
Container(
padding: EdgeInsets.only( top: SizeConfig.blockSizeHorizontal*2, left: SizeConfig.blockSizeHorizontal*6),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text("Monthly Summary", style: TextStyle(fontSize: SizeConfig.blockSizeHorizontal*6, color: Colors.black87,decoration: TextDecoration.none,),),
],
)
),
Container(
padding: EdgeInsets.only(top:SizeConfig.blockSizeHorizontal*2, left: SizeConfig.blockSizeHorizontal*3, right: SizeConfig.blockSizeHorizontal*3),
child: Divider(
color: Colors.black87,thickness: 2.0,
),
),
Container(
padding: EdgeInsets.only(left: SizeConfig.blockSizeHorizontal*6, top: SizeConfig.blockSizeHorizontal*4),
child: Row(
children: <Widget>[
Container(
child: Row(
children: <Widget>[
Text("Year - ", style: TextStyle(fontSize: SizeConfig.blockSizeHorizontal*4.5, color: Colors.black87,decoration: TextDecoration.none,),)
],
),
),
Container(
child: Row(
children: <Widget>[
Container(
child: DropdownButton(
value: _dpdValue,
underline: Container(),
isExpanded: true,
iconSize: 30.0,
items: _dropdownValues.map((val) {
return new DropdownMenuItem<String>(
value: val,
child: new Text(val),
);
}).toList(),
onChanged: (val) {
if (!mounted) return;
setState(
() {
_dpdValue = val;
},
);
},
),
)
],
),
)
],
)
)
],
)
),
margin: EdgeInsets.only(top: SizeConfig.blockSizeHorizontal*15, left: SizeConfig.blockSizeHorizontal*3, right: SizeConfig.blockSizeHorizontal*3),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(SizeConfig.blockSizeHorizontal*6),
),
),
);
},
transitionBuilder: (_, anim, __, child) {
return SlideTransition(
position: Tween(begin: Offset(0, 1), end: Offset(0, 0)).animate(anim),
child: child,
);
},
);
}
I have used an Alertdialog for this,, hope it offers insight to solving your problem,
int year = 1990;
List<String> months = ['January', 'February', 'March'];
List<String> years = [];
String option, month;
#override
void initState() {
super.initState();
for (int i = year; i < 2020; i++) {
years.add(i.toString());
}
}
Future<bool> errorDialog(context) async {
Size size = MediaQuery.of(context).size;
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return StatefulBuilder(builder: (context, setState) {
return AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0))),
content: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Monthly Summary"),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Year-'),
Container(
width: size.width * 0.5,
decoration: BoxDecoration(
border: Border.all(
color:Colors.amber),
borderRadius:
BorderRadius.all(Radius.circular(5))),
child: DropdownButtonFormField<String>(
decoration: InputDecoration(
contentPadding:
EdgeInsets.fromLTRB(10, 0, 10, 0),
filled: true,
fillColor: Colors.white,
hintText: 'Select Year',
hintStyle:
TextStyle(fontWeight: FontWeight.normal)),
value: option,
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.black),
onChanged: (String newValue) {
setState(() {
option = newValue;
});
},
validator: (value) {
if (value == null) {
return "Select Year";
}
return null;
},
items: years
.map<DropdownMenuItem<String>>((String option) {
return DropdownMenuItem<String>(
value: option,
child: Text(option),
);
}).toList(),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Month-'),
Container(
decoration: BoxDecoration(
border: Border.all(
color:Colors.amber),
borderRadius:
BorderRadius.all(Radius.circular(5))),
width: size.width * 0.5,
child: DropdownButtonFormField<String>(
decoration: InputDecoration(
contentPadding:
EdgeInsets.fromLTRB(10, 0, 10, 0),
filled: true,
fillColor: Colors.white,
hintText: 'Select Month',
hintStyle:
TextStyle(fontWeight: FontWeight.normal)),
value: month,
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.black),
onChanged: (String newValue) {
setState(() {
month = newValue;
});
},
validator: (value) {
if (value == null) {
return "Select Month";
}
return null;
},
items: months
.map<DropdownMenuItem<String>>((String option) {
return DropdownMenuItem<String>(
value: option,
child: Text(option),
);
}).toList(),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
color: Colors.amber,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(2.0))),
child: Text(
"CANCEL",
style: TextStyle(color: Colors.black),
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
color: Colors.amber,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(2.0))),
child: Text(
"SEARCH",
style: TextStyle(color: Colors.black),
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
],
),
),
],
),
),
);
});
});
}
Related
There are no error messages, but the delete button does not delete the selected content when I click on Delete.
The page shows a series of activities in sequence. The user should be able to edit or delete the individual activity when selected.
I do not find and understand the problem, can you help me find the error please ?
This is the code:
class AllTasksView extends GetView<HomeController> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: Get.height,
width: Get.width,
color: Theme.of(context).scaffoldBackgroundColor,
//padding: EdgeInsets.symmetric(horizontal: 30, vertical: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 50, left: 25, right: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'All Tasks',
style: kSubHeadTextStyle.copyWith(
color: Theme.of(context).primaryColorDark),
),
IconButton(
icon: Icon(
// FontAwesomeIcons.history,
FontAwesomeIcons.clockRotateLeft,
color: Theme.of(context).primaryColor,
size: 24,
),
onPressed: () {
Get.to(() => PastTasksView());
},
),
],
),
),
SizedBox(height: Get.height * 0.012),
GetBuilder<HomeController>(
id: 1,
builder: (controller) {
return Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
final task = controller.commingTasks[index]!;
return Slidable(
// actionPane: SlidableBehindActionPane(),
// actionExtentRatio: 0.2,
// controller: controller.slideC,
child: ExpandedContainer(
icon: task.taskImage,
title: task.taskTitle,
time: task.startTime,
desc: task.taskDesc,
ifDate: true,
date: DateFormat.yMMMd().format(task.taskDate!),
),
startActionPane: ActionPane(
motion: BehindMotion(),
children: [
SlidableAction(
onPressed: (context) {
// controller.slideC.activeState?.close();
Slidable.of(context)?.close();
controller.preUpdateTask(task);
showModalBottomSheet(
backgroundColor: Colors.transparent,
isScrollControlled: true,
context: context,
builder: (context) {
return BottomSheetContent(
buttonText: 'Update Task',
onSubmit: () {
controller.updateTask(task);
},
);
},
) as IconData;
},
label: "Update",
),
],
),
endActionPane: ActionPane(
motion: BehindMotion(),
children: [
SlidableAction(
onPressed: (context) {
// controller.slideC.activeState?.close();
Slidable.of(context)?.close();
controller.customDialogDel(context, task);
},
label: "Delete",
),
],
),
);
},
itemCount: controller.commingTasks.length,
),
);
},
),
],
),
),
);
}
}
This is the code to delete task by id
/// [ function to delete task by ID ]
deleteTask(Task task) async {
int index = allTasks.indexOf(task);
allTasks.removeAt(index);
taskRoutine();
reWriteTasks();
update([1, true]);
print(index);
}
And this is the code to delete where is the confirm dialog:
/// [ function to delete confirm dialog ]
Future<dynamic> customDialogDel(BuildContext context, Task task) {
return Get.dialog(Container(
margin: EdgeInsets.symmetric(
vertical: Get.height * 0.35, horizontal: Get.width * 0.18),
padding: EdgeInsets.all(20),
width: Get.width * 0.8,
height: Get.width * 0.8,
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
borderRadius: BorderRadius.circular(20),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'Delete Task!',
style: kSubHeadTextStyle.copyWith(
fontSize: 20,
color: Theme.of(context).primaryColorDark,
),
),
SizedBox(height: 20),
Text(
'Are you sure?',
style: kSubHeadTextStyle.copyWith(
fontSize: 16,
color: Theme.of(context).primaryColorDark,
),
),
SizedBox(height: 40),
Container(
width: 140,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
Get.back();
},
child: Container(
padding: EdgeInsets.symmetric(
vertical: 10, horizontal: 15),
child: Text(
'No',
style: kSubHeadTextStyle.copyWith(
fontSize: 16,
color: Theme.of(context).primaryColorDark,
),
),
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(
color: Theme.of(context).primaryColor),
borderRadius: BorderRadius.circular(10),
)),
),
SizedBox(width: 20),
GestureDetector(
onTap: () {
// slideC.activeState?.close();
Slidable.of(context)?.close();
deleteTask(task);
Get.back();
},
child: Container(
padding: EdgeInsets.symmetric(
vertical: 10, horizontal: 15),
child: Text(
'Yes',
style: kSubHeadTextStyle.copyWith(
fontSize: 16,
color: Theme.of(context).primaryColorDark,
),
),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(10),
)),
)
]),
),
],
),
),
),
),
));
}
}
i'm stuck on this problem for long time
in debug console
i don't know how to fix it please help
it says flexible while i did not use flexible widget.
i only used expanded and even when i remove expanded widget still have the same error
also i tried to remove everything except the list view builder widget i sill get the same error
this is the code:
import 'package:flutter/material.dart';
import 'package:todoy/Colors.dart';
import 'Taskslistview.dart';
import 'TasksListTile.dart';
import 'package:provider/provider.dart';
import 'Helper.dart';
bool isChekec = false;
class TasksScreen extends StatelessWidget {
Widget buildsheet(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
Container(
decoration: BoxDecoration(
color: Colors.white,
),
height: 400,
child: Padding(
padding: EdgeInsets.only(left: 50.0, right: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(
height: 10,
),
Center(
child: Text(
'Add Task',
style: TextStyle(
fontSize: 30,
color: Provider.of<Helper>(context).choosedcolor),
)),
TextField(
decoration: InputDecoration(
helperStyle: TextStyle(color: Colors.red),
helperText: Provider.of<Helper>(context).alreadyexist
? "this task already exist"
: " "),
textAlign: TextAlign.center,
onChanged: (value) {
if (Provider.of<Helper>(context, listen: false)
.tasknames
.contains(value)) {
Provider.of<Helper>(context, listen: false)
.alreadyture();
} else {
Provider.of<Helper>(context, listen: false)
.alreadyfalse();
}
Provider.of<Helper>(context, listen: false)
.addtaskname(value);
Provider.of<Helper>(context, listen: false)
.addtaskname(value);
print(Provider.of<Helper>(context, listen: false)
.addedtask);
},
),
SizedBox(
height: 10,
),
Container(
height: 50,
// ignore: deprecated_member_use
child: FlatButton(
color: Provider.of<Helper>(context).choosedcolor,
onPressed: () {
if (Provider.of<Helper>(context, listen: false)
.alreadyexist) {
print("you cant");
} else if (Provider.of<Helper>(context, listen: false)
.addedtask ==
"") {
print("ffgg");
} else {
Provider.of<Helper>(context, listen: false).addname(
Provider.of<Helper>(context, listen: false)
.addedtask);
Provider.of<Helper>(context, listen: false)
.add(TasksListTile(
isChcked: isChekec,
nameofthetask:
Provider.of<Helper>(context, listen: false)
.addedtask,
));
Provider.of<Helper>(context, listen: false)
.addedtask = "";
Navigator.pop(context);
}
},
child: Text(
"ADD",
style: TextStyle(color: Colors.white, fontSize: 20),
)),
)
],
),
),
),
],
),
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Provider.of<Helper>(context).choosedcolor,
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.only(left: 300.0, top: 30, right: 15),
child: GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => ColorsScreen()));
},
child: CircleAvatar(
radius: 35,
backgroundColor: Colors.white,
child: Icon(
Icons.invert_colors,
size: 40,
color: Provider.of<Helper>(context).choosedcolor,
)),
),
),
Padding(
padding: EdgeInsets.only(left: 40.0, top: 40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(left: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CircleAvatar(
radius: 35,
backgroundColor: Colors.white,
child: Icon(
Icons.list,
size: 40,
color: Provider.of<Helper>(context).choosedcolor,
)),
Padding(
padding: const EdgeInsets.only(right: 30.0),
child: Container(
height: 67,
child: FittedBox(
child: FloatingActionButton(
child: Icon(Icons.delete_forever,
size: 40,
color: Provider.of<Helper>(context)
.choosedcolor),
backgroundColor: Colors.white,
onPressed: () {
Provider.of<Helper>(context, listen: false)
.remove();
},
),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, left: 10, bottom: 10),
child: Text(
"Todoy",
style: TextStyle(color: Colors.white, fontSize: 40),
textAlign: TextAlign.start,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
' ${Provider.of<Helper>(context).tasks.length} Tasks',
style: TextStyle(color: Colors.white, fontSize: 40),
textAlign: TextAlign.start,
),
Padding(
padding: const EdgeInsets.only(right: 30.0),
child: Container(
height: 70,
child: FittedBox(
child: FloatingActionButton(
child: Text(
"+",
style: TextStyle(
fontSize: 50,
color: Provider.of<Helper>(context)
.choosedcolor),
),
backgroundColor: Colors.white,
onPressed: () {
showModalBottomSheet(
context: context, builder: buildsheet);
},
),
),
),
),
],
),
],
),
),
SizedBox(
height: 20,
),
Expanded(
child: Container(
padding: EdgeInsets.only(left: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(40),
topRight: Radius.circular(40))),
child: Taskslistview(),
),
),
],
),
),
);
}
}
inside Tasklistview:
class Taskslistview extends StatelessWidget {
#override
Widget build(BuildContext context) {
bool isChecked = false;
return ListView.builder(
itemCount: Provider.of<Helper>(context).tasks.length,
itemBuilder: (context, index) {
return TasksListTile(
isChcked: isChecked,
nameofthetask:
Provider.of<Helper>(context, listen: false).tasknames[index],
);
},
);
}
}
please help i tried everything to fix it nothing worked
I have a form builder application, I have stateless widgets which get added to list view, each widget has a delete icon, I want to delete the widget and update the list view.
one of the code widget code is this
class HeaderTextWidget extends StatelessWidget {
final VoidCallback onDelete;
HeaderTextWidget({Key key, this.onDelete}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 12.0),
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.only(
topRight: Radius.circular(15.0),
topLeft: Radius.circular(15.0),
),
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(6.0),
child: Text(
'Header',
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
),
),
),
Card(
elevation: 5.0,
color: Colors.blueGrey.shade50,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15.0),
topRight: Radius.circular(15.0),
),
),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 10.0, 8.0, 10.0),
child: TextField(
textCapitalization: TextCapitalization.words,
keyboardType: TextInputType.text,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
decoration: InputDecoration(
hintText: 'untitled header',
hintStyle: TextStyle(
color: Colors.grey,
fontStyle: FontStyle.italic,
fontSize: 14.0,
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 20.0),
child: TextField(
textCapitalization: TextCapitalization.words,
keyboardType: TextInputType.text,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.normal,
),
decoration: InputDecoration(
hintText: 'Description (optional)',
hintStyle: TextStyle(
color: Colors.grey,
fontSize: 14.0,
),
),
),
),
Divider(
indent: 4.0,
endIndent: 4.0,
thickness: 2.0,
),
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
IconButton(
icon: Icon(Icons.content_copy),
iconSize: 24.0,
color: Colors.blue,
onPressed: () {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('COpy'),
),
);
},
),
IconButton(
icon: Icon(Icons.delete),
iconSize: 24.0,
color: Colors.red,
onPressed: this.onDelete,
),
VerticalDivider(
thickness: 2.0,
endIndent: 6.0,
indent: 4.0,
),
Padding(
padding: const EdgeInsets.only(right: 12.0),
child: SwitchWidget(),
),
],
),
),
],
),
),
],
),
);
}
}
This is my Listview builder
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FormBuilder(
key: widget.fbKey,
autovalidate: true,
child: Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView.builder(
itemCount: widget.data.widgets.length,
controller: _scrollController,
itemBuilder: (context, index) {
return widget.data.widgets[index];
},
),
),
)),
],
),
);
This is how the widget is being added the view is getting changed from selected the widget to List view builder page, when clicked on that particular icon. Where should be the delete function be added, in the List view or in the widget itself ?
Scaffold(
appBar: AppBar(
title: Text('Form Widgets'),
),
body: LayoutBuilder(
builder:
(BuildContext context, BoxConstraints viewPointConstrainsts) {
return SingleChildScrollView(
padding: EdgeInsets.all(12.0),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewPointConstrainsts.maxHeight,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FormWidget(
key: UniqueKey(),
iconData: Icons.title,
widgetTxT: 'Header',
onTap: () {
setState(() {
widget.data.widgets.add(HeaderTextWidget());
widget.pickWidgetsView = false;
});
},
),
Try the following approach:
Store only the data, not the Widget itself in the list
List<DataModel> data = []
Create list view item using createListViewItem() which should return widget as the following
ListView.builder(
itemCount: widget.dataList.length,
controller: _scrollController,
itemBuilder: (context, index) {
return createListViewItem(index);
},
),
Now inside createListViewItem(index) you can create data as per widget.dataList[index] and delete the list item on click of delete icon
setState(){
widget.dataList.deleteAt(index);
}
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DropdownButton(
items: _Mothe.map(
(String dropdownMenuItem) {
return DropdownMenuItem<String>(
value: dropdownMenuItem,
child: Text(dropdownMenuItem),
);
},
).toList(),
onChanged: (String? value) {
setState(
() {
name == value!;
},
);
},
value: name,
isExpanded: true,
icon: SizedBox(),
),
],
),
);
}
I've tried to create form to input something from textfield to database using rest service, it worked just fine from the first try, but it got error the next time I tried, the error said there was something wrong with the GlobalkKey, so it's maybe around here.
class _DeliveryRecieverState extends State<DeliveryReciever> {
List datas;
File imagePath;
bool validasi = false;
String namaPenerima;
final _keyFormReceiver = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
datas = this.datas;
print(datas);
return DefaultTabController(
length: 1,
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
bottom: TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.local_shipping),
text: "Bukti Delivery",
),
],
),
elevation: 0.1,
// backgroundColor: Colors.cyan[800],
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF17ead9), Color(0xFF6078ea)]),
),
),
title: Text(
"Delivery",
style: TextStyle(
fontFamily: "Popins-Bold",
fontSize: ScreenUtil.getInstance().setSp(46),
letterSpacing: .6,
fontWeight: FontWeight.bold,
),
),
actions: <Widget>[
],
),
body: TabBarView(
children: <Widget>[
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(
left: 15.0, right: 15.0, top: 15.0, bottom: 15.0),
child: Column(
children: <Widget>[
Container(
width: double.infinity,
height: ScreenUtil.getInstance().setHeight(470),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(0.0, 15.0),
blurRadius: 15.0),
BoxShadow(
color: Colors.black12,
offset: Offset(0.0, -10.0),
blurRadius: 10.0)
]),
child: Padding(
padding: EdgeInsets.only(
left: 16.0, right: 16.0, top: 16.0),
child: Form(
key: _keyFormReceiver,
autovalidate: validasi,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Nama Penerima",
style: TextStyle(
fontSize:
ScreenUtil.getInstance().setSp(30),
fontFamily: "Poppins-Bold",
letterSpacing: .6),
),
SizedBox(
height:
ScreenUtil.getInstance().setHeight(30),
),
TextFormField(
validator: validasiReceivername,
onSaved: (String nama) {
namaPenerima = nama;
},
decoration: InputDecoration(
hintText: "Nama Penerima",
hintStyle: TextStyle(
color: Colors.grey,
fontSize: 12.0)),
),
SizedBox(
height:
ScreenUtil.getInstance().setHeight(50),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(10.0),
child: RaisedButton(
elevation: 7.0,
color: Colors.green,
padding: EdgeInsets.all(20.0),
child: Text("LANJUT"),
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10)),
onPressed: () {
parseData();
},
),
),
],
),
],
),
)),
),
],
),
),
),
],
),
bottomNavigationBar: Container(
height: 55.0,
child: BottomAppBar(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF17ead9), Color(0xFF6078ea)]),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.home, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => halamanUtama()),
);
},
),
IconButton(
icon: Icon(Icons.nature_people, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UpcomingDelivery()),
);
},
),
IconButton(
icon: Icon(Icons.local_shipping, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ListDelivery()),
);
},
),
],
),
),
),
),
));
}
String validasiReceivername(String value) {
if (value.length == 0) {
//Toast.show("Password more than 4 ", context,duration: Toast.LENGTH_SHORT, gravity: Toast.CENTER);
return "Nama penerima tidak boleh kosong.";
} else {
return null;
}
}
void parseData() async {
if (_keyFormReceiver.currentState.validate()) {
_keyFormReceiver.currentState.save();
_keyFormReceiver.currentState.reset();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CustomerSignatureProof(
created_name: widget.created_name,
wmsorders_id: widget.wmsorders_id,
imagePath: widget.imagePath,
imageName: widget.imageName,
receiverName: namaPenerima,
upcoming_id: widget.upcoming_id,
upcoming_sku: widget.upcoming_sku,
upcoming_sak: widget.upcoming_sak,
upcoming_qty: widget.upcoming_qty,
upcoming_shipstatid: widget.upcoming_shipstatid,
upcoming_picname: widget.upcoming_picname,
upcoming_pictelp: widget.upcoming_pictelp,
upcoming_ordermultipleid: widget.upcoming_ordermultipleid,
upcoming_orderdetid: widget.upcoming_orderdetid,
upcoming_coordinatorid: widget.upcoming_coordinatorid,
upcoming_shipmentid: widget.upcoming_shipmentid)));
}
}
}
Here is the error in terminal,
Have anybody face the same probles as me, please give your guidance..
Here is my issue: The button should Not overlap the textfield.
Notice that I added a SingleChildScrollView(). The user can still scroll up and achieve the desired the result but I want to make it automatic:
Here is my code:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_masked_text/flutter_masked_text.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:talking_dodo/dodo/pages/payment/credit_card.dart';
class WithdrawPage extends StatefulWidget {
#override
WithdrawPageState createState() {
return new WithdrawPageState();
}
}
class WithdrawPageState extends State<WithdrawPage> {
bool isDataAvailable = true;
int _radioValue = 0;
MaskedTextController ccMask =
MaskedTextController(mask: "0000 0000 0000 0000");
Widget _buildBody() {
return Stack(
children: <Widget>[
SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(
left: 16.0, right: 16.0, top: 16.0, bottom: 16.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 18.0),
child: Text('Please select withdrawal method below'),
),
],
),
Container(
margin: EdgeInsets.only(top: 12.0),
child: Row(
children: <Widget>[
new Radio(
value: 0,
groupValue: _radioValue,
onChanged: ((value) {
setState(() {
_radioValue = value;
});
}),
),
Text(
'ATM Withdrawal',
),
],
),
),
Container(
height: 220.0,
padding: EdgeInsets.only(left: 20.0, right: 10.0),
margin: const EdgeInsets.all(2.0),
decoration: BoxDecoration(
// color: Colors.white,
border: Border.all(color: Colors.black),
borderRadius: BorderRadius.all(Radius.circular(12.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Bullet('Visit mcb Branch'),
Bullet('Select "Dodo Wallet" in the options'),
Bullet('Select the amount to withdraw'),
Bullet('Input your dodo wallet pin'),
Bullet(
'Input the code in the input box below and click withdraw'),
Padding(
padding: const EdgeInsets.only(top:18.0),
child: TextField(
controller: ccMask,
keyboardType: TextInputType.number,
maxLength: 19,
style:
TextStyle(fontFamily: 'Raleway', color: Colors.black),
decoration: InputDecoration(
labelText: "Code",
labelStyle: TextStyle(fontWeight: FontWeight.bold),
border: OutlineInputBorder()),
),
),
],
),
),
Row(
children: <Widget>[
new Radio(
value: 1,
groupValue: _radioValue,
onChanged: ((value) {
setState(() {
_radioValue = value;
});
}),
),
Text(
'Transfer to card',
),
],
),
],
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: isDataAvailable
? Expanded(
child: ButtonTheme(
height: 65.0,
child: RaisedButton(
color: Theme.of(context).primaryColorLight,
child: Text('Withdraw funds'),
onPressed: () => showSuccessDialog()),
),
)
: Padding(
padding: EdgeInsets.only(bottom: 10.0),
child: CircularProgressIndicator()),
),
],
),
),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Withdrawal"),
),
body: _buildBody(),
);
}
void showSuccessDialog() {
setState(() {
isDataAvailable = false;
Future.delayed(Duration(seconds: 1)).then((_) => goToDialog());
});
}
goToDialog() {
setState(() {
isDataAvailable = true;
});
showDialog(
context: context,
barrierDismissible: true,
builder: (context) => Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
successTicket(),
SizedBox(
height: 10.0,
),
FloatingActionButton(
backgroundColor: Colors.black,
child: Icon(
Icons.clear,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context);
Navigator.of(context).pushNamed('/chat');
},
)
],
),
),
));
}
successTicket() => Container(
width: double.infinity,
padding: const EdgeInsets.all(16.0),
child: Material(
clipBehavior: Clip.antiAlias,
elevation: 2.0,
borderRadius: BorderRadius.circular(4.0),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
ProfileTile(
title: "Thank You!",
textColor: Colors.purple,
subtitle: "Your transaction was successful",
),
ListTile(
title: Text("Date"),
subtitle: Text("26 June 2018"),
trailing: Text("11:00 AM"),
),
ListTile(
title: Text("Daniel Daniel"),
subtitle: Text("gmail#daniel.com"),
trailing: CircleAvatar(
radius: 20.0,
backgroundImage: NetworkImage(
"https://avatars0.githubusercontent.com/u/12619420?s=460&v=4"),
),
),
ListTile(
title: Text("Amount"),
subtitle: Text("\$423.00"),
trailing: Text("Completed"),
),
Card(
clipBehavior: Clip.antiAlias,
elevation: 0.0,
color: Colors.grey.shade300,
child: ListTile(
leading: Icon(
FontAwesomeIcons.ccAmex,
color: Colors.blue,
),
title: Text("Credit/Debit Card"),
subtitle: Text("Amex Card ending ***6"),
),
),
],
),
),
),
);
}
class Bullet extends Text {
const Bullet(
String data, {
Key key,
TextStyle style,
TextAlign textAlign,
TextDirection textDirection,
Locale locale,
bool softWrap,
TextOverflow overflow,
double textScaleFactor,
int maxLines,
String semanticsLabel,
}) : super(
'• $data',
key: key,
style: style,
textAlign: textAlign,
textDirection: textDirection,
locale: locale,
softWrap: softWrap,
overflow: overflow,
textScaleFactor: textScaleFactor,
maxLines: maxLines,
semanticsLabel: semanticsLabel,
);
}
What you're looking for is the scrollPadding parameter of textfield. Flutter automatically scrolls the view to the top of the keyboard when the textfield is focused, but it has no idea about the fact that you've placed a button that sits at the bottom of the screen.
With your current code, you could simply replace scrollPadding with padding that has a larger bottom (i.e. the size of the yellow button) and flutter should do the rest for you.