It's a problem that has been going on for too long. I tried with SimpleAutoComplete or TypeAheadField but I have the same problem.
Simple Auto Complete
Type ahead
With two elements, my sort is succesfull but when i click on the element, I have this three possibilities :
Bad state: Too many elements
return null in my item
never call the action
Autocomplete :
final _nameContributorTextFormFieldDetailsCreateMission = Padding(
padding: EdgeInsets.only(top: 12.0, left: 12.0, bottom: 12.0),
child: SizedBox(
height: 100,
width: 300,
child: SimpleAutocompleteFormField<Employee>(
key: key,
controller: _searchText2Controller,
focusNode: _focusNode,
itemBuilder: (context, contributor) => Padding(
padding: EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Text(
contributor.lastname,
style: TextStyle(fontWeight: FontWeight.bold),
),
Padding(
padding: EdgeInsets.only(left: 4.0),
child: Text(contributor.firstname),
),
],
),
),
onSearch: (search) async => model.employees
.where((contributor) =>
contributor.firstname
.toLowerCase()
.contains(search.toLowerCase()) ||
contributor.lastname
.toLowerCase()
.contains(search.toLowerCase()))
.toList(),
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Nom',
),
itemFromString: (string) => model.employees.singleWhere(
(contributor) =>
contributor.firstname.toLowerCase() == string.toLowerCase(),
orElse: () => null),
onFieldSubmitted: (item) {
print(item);
_searchTextController.text = "${item.firstname}";
},
onSaved: (item) {
print(item);
},
/*onChanged: (Store value) {
model.store = value;
model.setClientOnChangedValue(model.store);
},
onSaved: (Store value) {
model.store = value;
model.setClientOnSavedValue(model.store);
}, */
// validator: (contributor) => contributor == null ? 'Invalid' : null,
),
),
);
TypeAhead :
Padding(
padding: EdgeInsets.only(top: 12.0, left: 12.0, bottom: 12.0),
child: SizedBox(
width: 300,
child: TypeAheadField(
textFieldConfiguration: TextFieldConfiguration(
autofocus: true,
controller: model.typeAheadController,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: 'Client'),
),
suggestionsCallback: (pattern) async {
print("toto $pattern");
return await model.getSuggestionsClientName(pattern);
},
itemBuilder: (context, suggestion) {
return ListTile(
title: Text(suggestion.toString()),
);
},
transitionBuilder: (context, suggestionsBox, controller) {
print("SuggestionsBox : $suggestionsBox");
print(controller);
return suggestionsBox;
},
onSuggestionSelected: (suggestion) {
print("onclick");
model.typeAheadController.text = suggestion;
},
),
),
);
Or last try, i died my sort method : (this method return item null)
ListView(
children: <Widget>[
SimpleAutocompleteFormField<Employee>(
decoration: InputDecoration(
labelText: 'Person', border: OutlineInputBorder()),
suggestionsHeight: 80.0,
itemBuilder: (context, person) => Padding(
padding: EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(person.firstname,
style: TextStyle(fontWeight: FontWeight.bold)),
Text(person.lastname)
]),
),
onSearch: (search) async => model.employees
.where((person) =>
person.firstname
.toLowerCase()
.contains(search.toLowerCase()) ||
person.lastname
.toLowerCase()
.contains(search.toLowerCase()))
.toList(),
itemFromString: (string) => model.employees.singleWhere(
(person) =>
person.firstname.toLowerCase() ==
string.toLowerCase(),
orElse: () => null),
onFieldSubmitted: (item){
print(item);
},
validator: (person) =>
person == null ? 'Invalid person.' : null,
),
],
),
Solution :
Because in FlutterWeb, this widget is bugged.
For TypeAhead
itemBuilder: (context, suggestion) {
return GestureDetector(
onPanDown: (_) {
model.typeAheadController.text = suggestion;
},
child: Container(
color: Colors.white,
child: ListTile(
title: Text(suggestion.toString()),
),
),
);
},
Related
I'm coding a search system for the Flutter application I've developed. I'm having a problem with the back-end. First I pull the data from Firebase Firestore. Then I convert it to Model structure.
The code of the search system:
StreamBuilder(
stream: db.collection("DebrisPeoples").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
final List<DebrisPeopleModel> data = snapshot.data!.docs
.map((e) => DebrisPeopleModel.fromDocument(e))
.toList(); // To Model code
return Column(
children: [
const SizedBox(height: 10),
SizedBox(
width: MediaQuery.of(context).size.width * 0.95,
child: TextFormField(
decoration: InputDecoration(
prefixIcon: const Icon(Icons.search),
contentPadding: const EdgeInsets.only(),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
),
),
onChanged: (value) {
final find = data.where(
(element) => data.contains(element.nameSurname));
print(find); // PROBLEM - NOT WORKING
},
),
),
SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.8,
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Icon(
data[index].personSize == 1
? Icons.person
: Icons.people,
),
title: Text(data[index].nameSurname.toString()),
subtitle: Text(
"${data[index].city} / ${data[index].district}",
),
trailing: IconButton(
icon: const Icon(Icons.info),
onPressed: () {
Get.to(const UnderRublePeopleDetailPage(),
arguments: data[index]);
print(data[index].nameSurname);
},
),
),
);
},
),
),
],
);
}
},
),
I'm having the problem in the query part. My goal is, for example, if there is a record in the form of ABC, I want it to appear in the results even if the user searches for A or AB.
Then I want the results to be displayed in the list. I will be grateful for your help :)
To change search results:
final find = data.where((element) => element
.nameSurname!
.toLowerCase()
.contains(value.toLowerCase()));
print(find);
setState(() {
data = find.toList();
print(data);
});
I tried to make such a search system. However, the results in the ListView do not change as I enter the TextFormField.
Your onChanged code should be as following.
onChanged: (value) {
final find = data.where(
(element) => element.nameSurname.toLowerCase().contains(value.toLowerCase()));
print(find);
}
Make sure you are managing the state to reflect the changes on UI.
Edited
final controller = TextEditingController();//Keep this as a field
StreamBuilder(
stream: db.collection("DebrisPeoples").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
final searchText = controller.text.trim().toLowerCase();
final List<DebrisPeopleModel> data = snapshot.data!.docs
.map((e) => DebrisPeopleModel.fromDocument(e))
.where((e) => searchText.isEmpty || e.nameSurname!
.toLowerCase().contains(searchText))
.toList(); // To Model code
return Column(
children: [
const SizedBox(height: 10),
SizedBox(
width: MediaQuery
.of(context)
.size
.width * 0.95,
child: TextFormField(
controller: controller,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.search),
contentPadding: const EdgeInsets.only(),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
),
),
onChanged: (value) {
setState((){ });
},
),
),
SizedBox(
width: double.infinity,
height: MediaQuery
.of(context)
.size
.height * 0.8,
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Icon(
data[index].personSize == 1
? Icons.person
: Icons.people,
),
title: Text(data[index].nameSurname.toString()),
subtitle: Text(
"${data[index].city} / ${data[index].district}",
),
trailing: IconButton(
icon: const Icon(Icons.info),
onPressed: () {
Get.to(const UnderRublePeopleDetailPage(),
arguments: data[index]);
print(data[index].nameSurname);
},
),
),
);
},
),
),
],
);
}
},
)
This the form where I'm trying to move the focus. All is working fine till the field title, where I want to move it to a textField phone number but in doing so instead of moving the focus the soft keyboard disappears. I tried to attached scrollController to the SingleScrollView and then move it in onSaved in the textfield before this one I want to get focus:
controller.singleSclollViewController.jumpTo(controller.singleSclollViewController.position.maxScrollExtent);
But it is doing nothing.
This is the complete form with that problem
Form(
key: controller.formKey,
child: SingleChildScrollView(
controller: controller.singleSclollViewController,
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
verticalSpaceMedium,
Image.asset(
'assets/graphics/data.png',
),
Container(
padding: EdgeInsets.symmetric(horizontal: 40),
child: GetBuilder<HomeController>(
builder: (builderController) =>
builderController.isPosition
? CustomTextField(
autofocus: true,
focusNode:
controller.adressFocusNode,
validate: (text) => controller
.validateTextField(text),
maxline: 4,
minLine: 2,
height: 80.h,
width: 0.8.sw,
controller:
controller.adressController,
color:
AppColors.primaryColorShade,
//adress
lableText: 'адреса',
)
: CircularProgressIndicator()),
),
verticalSpaceSmall,
Container(
padding: EdgeInsets.symmetric(
horizontal: 40,
vertical: 10,
),
child: TypeAheadFormField<City>(
validator: (text) {
if (globalController
.doesSuggestionExist) {
//there is no such available city
return 'такого доступного міста немає';
}
return controller
.validateTextField(text ?? '');
},
textFieldConfiguration:
TextFieldConfiguration(
controller: controller.cityController,
decoration:
outlineInputTextFormFieldStyle!
.copyWith(
label: Text(
//city
'місто',
style: textfieldLableStyle,
)),
),
onSuggestionSelected: (City city) {
controller.cityController.text =
city.name;
controller.nameFocusNode.requestFocus();
},
itemBuilder: (_, City city) {
return ListTile(
leading: Icon(Icons.location_city),
title: Text(
city.name,
style: headingBlackStyle,
),
);
},
suggestionsCallback: (pattern) async {
return await globalController
.getSuggestions(pattern, '');
}),
),
verticalSpaceSmall,
OneLineTextField(
focusNode: controller.nameFocusNode,
onSubmit: () {
controller.nameFocusNode.unfocus();
controller.titleFocusNode.requestFocus();
},
keybordhType: TextInputType.name,
validator: (text) {
return controller
.validateTextField(text ?? '');
},
//name/"Ім'я та прізвище"
lable: "Ім'я та прізвище",
maxLenght: 25,
controller: controller.nameController),
verticalSpaceSmall,
OneLineTextField(
onSubmit: () {
controller.singleSclollViewController
.jumpTo(controller
.singleSclollViewController
.position
.maxScrollExtent);
controller.phoneFocusNode.requestFocus();
},
focusNode: controller.titleFocusNode,
maxLenght: 25,
keybordhType: TextInputType.name,
validator: (text) {
return controller
.validateTextField(text ?? '');
},
//title/"потрібен титул"
lable: 'Назва оголошення',
controller: controller.titleController),
verticalSpaceSmall,
OneLineTextField(
focusNode: controller.phoneFocusNode,
onSubmit: () => controller
.descripotionFocusNode
.requestFocus(),
maxLenght: 15,
keybordhType: TextInputType.number,
validator: (text) {
return controller
.validateTextField(text ?? '');
},
//phone number/ "телефонний номер"
lable: 'телефонний номер',
controller:
controller.contactNumberController),
verticalSpaceSmall,
Container(
padding: EdgeInsets.symmetric(horizontal: 40),
child: CustomTextField(
onSubmit: () => controller
.descripotionFocusNode
.unfocus(),
focusNode: controller.descripotionFocusNode,
maxLenght: 400,
validate: (text) =>
controller.validateTextField(text),
maxline: 10,
minLine: 5,
height: 120.h,
width: 0.8.sw,
controller: controller.descriptionController,
color: AppColors.primaryColorShade,
//description
lableText: 'опис',
),
),
],
),
),
),
I can't get the FormBuilderDateTimePicker to display the calendar. The clock works for my start and end time and the calendar works if I use the FormBuilderDateRangePicker but I can't get the calendar to open on FormBuilderDateTimePicker.
Here's my code.
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
import 'package:komae_v2/data.dart';
class BookASit extends StatefulWidget {
#override
BookASitState createState() {
return BookASitState();
}
}
class BookASitState extends State<BookASit> {
var data;
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
final ValueChanged _onChanged = (val) => print(val);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Book A Sit!'),
),
body: Padding(
padding: const EdgeInsets.all(10),
child: ListView(
children: <Widget>[
FormBuilder(
// context,
key: _fbKey,
autovalidate: true,
readOnly: false,
child: Column(
children: <Widget>[
SizedBox(height: 15),
FormBuilderTypeAhead(
decoration: const InputDecoration(
labelText: 'Select a Child',
),
attribute: 'child',
onChanged: _onChanged,
itemBuilder: (context, children) {
return ListTile(
title: Text(children),
);
},
controller: TextEditingController(text: ''),
initialValue: '',
suggestionsCallback: (query) {
if (query.isNotEmpty) {
var lowercaseQuery = query.toLowerCase();
return allChildren.where((children) {
return children
.toLowerCase()
.contains(lowercaseQuery);
}).toList(growable: false)
..sort((a, b) => a
.toLowerCase()
.indexOf(lowercaseQuery)
.compareTo(
b.toLowerCase().indexOf(lowercaseQuery)));
} else {
return allChildren;
}
},
),
SizedBox(height: 15),
Row(
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child: Row(
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child: FormBuilderDateTimePicker(
attribute: 'time',
onChanged: _onChanged,
inputType: InputType.time,
decoration: const InputDecoration(
labelText: 'Start Time',
),
validator: (val) => null,
initialTime: TimeOfDay(hour: 8, minute: 0),
initialValue: DateTime.now(),
// readonly: true,
),
),
],
),
),
Flexible(
fit: FlexFit.loose,
child: Row(
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child: FormBuilderDateTimePicker(
attribute: 'time',
onChanged: _onChanged,
inputType: InputType.time,
decoration: const InputDecoration(
labelText: 'End Time',
),
validator: (val) => null,
initialTime: TimeOfDay(hour: 8, minute: 0),
// initialValue: DateTime.now(),
// readonly: true,
),
),
],
),
),
],
),
SizedBox(height: 15),
FormBuilderDateTimePicker(
attribute: "date",
initialDate: DateTime.now(),
initialValue: DateTime.now(),
inputType: InputType.date,
format: DateFormat("MM-dd-yyyy"),
decoration: InputDecoration(labelText: "Date"),
),
SizedBox(height: 15),
FormBuilderChipsInput(
decoration: const InputDecoration(
labelText:
'Select contacts to send the sit request to'),
attribute: 'chips_test',
onChanged: _onChanged,
maxChips: 5,
findSuggestions: (String query) {
if (query.isNotEmpty) {
var lowercaseQuery = query.toLowerCase();
return contacts.where((profile) {
return profile.name
.toLowerCase()
.contains(query.toLowerCase()) ||
profile.email
.toLowerCase()
.contains(query.toLowerCase());
}).toList(growable: false)
..sort((a, b) => a.name
.toLowerCase()
.indexOf(lowercaseQuery)
.compareTo(b.name
.toLowerCase()
.indexOf(lowercaseQuery)));
} else {
return const <Contact>[];
}
},
chipBuilder: (context, state, profile) {
return InputChip(
key: ObjectKey(profile),
label: Text(profile.name),
// avatar: CircleAvatar(
// backgroundImage: NetworkImage(profile.imageUrl),
// ),
onDeleted: () => state.deleteChip(profile),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
);
},
suggestionBuilder: (context, state, profile) {
return ListTile(
key: ObjectKey(profile),
leading: CircleAvatar(child: Text('A')
// backgroundImage: NetworkImage(profile.imageUrl),
),
title: Text(profile.name),
subtitle: Text(profile.email),
onTap: () => state.selectSuggestion(profile),
);
},
),
],
),
),
SizedBox(height: 15),
Row(
children: <Widget>[
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
'Submit',
style: TextStyle(color: Colors.white),
),
onPressed: () {
if (_fbKey.currentState.saveAndValidate()) {
print(_fbKey.currentState.value);
} else {
print(_fbKey.currentState.value);
print('validation failed');
}
},
),
),
SizedBox(width: 20),
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
'Reset',
style: TextStyle(color: Colors.white),
),
onPressed: () {
_fbKey.currentState.reset();
},
),
),
],
),
],
),
),
);
}
}
My debugger highlights this line:
newValue = await _showDatePicker(context, currentValue) ?? currentValue;
with the exception
_failedAssertion: "initialEntryMode != null"
message: null
_messageString: "is not true"
As the assertion says that the assertion initialEntryMode != null, the initialEntryMode parameter is null, which is not allowed by this widget(at least for your current configuration). Add a value for this parameter when FormBuilderDateTimePicker is used.
Ex:
FormBuilderDateTimePicker(
attribute: "date",
initialDate: DateTime.now(),
initialValue: DateTime.now(),
inputType: InputType.date,
format: DateFormat("MM-dd-yyyy"),
decoration: InputDecoration(labelText: "Date"),
initialEntryMode: DatePickerEntryMode.calendar,
),
I am facing a problem, I have a autocompletetextfield its work fine but contoller not working when i settext throw controller nothing happen, others work fine (quantity and price controllers)...
Examples:
On search itemSubmit
here is my TextField
AutoCompleteTextField<Services>(
controller: _serviceController,
itemSorter: (Services a, Services b) {
return a.name.compareTo(b.name);
},
decoration: InputDecoration(
fillColor: Colors.white,
labelText: "Service",
filled: true,
),
style: TextStyle(
fontFamily: "Light",
),
suggestions: Services.list,
itemFilter: (Services suggestion, String query) {
return suggestion.name.toLowerCase().startsWith(query.toLowerCase());
},
itemBuilder: (BuildContext context, Services suggestion) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(suggestion.name,
style: TextStyle(
fontSize: 16.0
),
),
],
),
);
},
key: null,
itemSubmitted: (Services data) {
setState(() {
**_serviceController.text = data.name;**
_priceController.text = data.price;
_quantityController.text = data.quantity.toString();
});
},
),
You should give Key, just assign a GlobalKey to AutoCompleteTextField Widget
GlobalKey key = new GlobalKey<AutoCompleteTextFieldState<Services>>();
AutoCompleteTextField<Services>(
controller: _serviceController,
itemSorter: (Services a, Services b) {
return a.name.compareTo(b.name);
},
decoration: InputDecoration(
fillColor: Colors.white,
labelText: "Service",
filled: true,
),
style: TextStyle(
fontFamily: "Light",
),
suggestions: Services.list,
itemFilter: (Services suggestion, String query) {
return suggestion.name.toLowerCase().startsWith(query.toLowerCase());
},
itemBuilder: (BuildContext context, Services suggestion) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(suggestion.name,
style: TextStyle(
fontSize: 16.0
),
),
],
),
);
},
key: key,
itemSubmitted: (Services data) {
setState(() {
_serviceController.text = data.name;
_priceController.text = data.price;
_quantityController.text = data.quantity.toString();
});
},
),
I am having problems with the validate() function. I can't understand why it skips some validator:(){}. Here is my code:
import 'package:flutter/material.dart';
class TestScreen extends StatefulWidget {
static const routeName = '/test-screen';
#override
_TestScreenState createState() => _TestScreenState();
}
class _TestScreenState extends State<TestScreen> {
final _form = GlobalKey<FormState>();
Future<void> _saveForm() async {
final isValid = _form.currentState.validate();
if (!isValid) {
return;
}
}
Widget _buildContainer(Widget child) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(10),
),
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
height: 200,
width: 300,
child: child,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Test',
style: Theme.of(context).textTheme.title,
),
automaticallyImplyLeading: false,
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
key: _form,
child: ListView(
children: <Widget>[
TextFormField(
initialValue: '',
decoration: InputDecoration(labelText: 'Name'),
validator: (value) {
if (value.isEmpty) {
return 'Insert something';
}
return null;
},
),
TextFormField(
initialValue: '',
decoration: InputDecoration(labelText: 'Number'),
keyboardType: TextInputType.number,
validator: (value) {
if (int.tryParse(value) == null) {
return 'Insert a number';
}
return null;
},
),
SizedBox(height: 20),
_buildContainer(
ListView(
children: <Widget>[],
),
),
Text(
'Text-Test1',
textAlign: TextAlign.center,
),
Slider(
value: 1,
divisions: 3,
min: 0.0,
max: 3.0,
label: 'Test',
onChanged: (newValue) {},
),
SizedBox(
height: 20,
),
Text(
'Text-Test2',
textAlign: TextAlign.center,
),
Slider(
value: 3,
divisions: 4,
min: 0.0,
max: 4.0,
label: 'Nothing2',
onChanged: (newValue) {},
),
SizedBox(
height: 20,
),
Row(
children: <Widget>[
Text('RandomLabel'),
Spacer(),
Container(
width: 100,
child: TextFormField(
initialValue: '',
keyboardType: TextInputType.number,
validator: (value) {
if (int.tryParse(value) == null) {
return 'Insert a number';
}
return null;
},
),
),
],
),
SizedBox(
height: 20,
),
Text(
'Test 2',
textAlign: TextAlign.center,
),
_buildContainer(
ListView.builder(
itemCount: 0,
itemBuilder: (ctx, index) {
return ListTile(
title: Text('hello'),
subtitle: Text('world'),
);
},
),
),
TextFormField(
initialValue: '',
minLines: 4,
maxLines: 4,
decoration: InputDecoration(labelText: 'Text'),
validator: (value) {
if (value.isEmpty) {
return 'Insert something';
}
return null;
},
),
FlatButton.icon(
icon: Icon(Icons.check),
label: Text('Done'),
onPressed: () {
_saveForm();
},
),
],
),
),
),
);
}
}
If I click on Done, it skips the first two TextFormFields and goes to validate the one in the Row. Obviously it is not what I want. How to fix it and validate all the TextFormFields?
Wrapping form fields with ListView is a bad idea: when user scrolls to submit button some inputs are disposed because they are off-screen. You have to replace ListView with Column widget and wrap all form in SingleChildScrollView:
class TestScreen extends StatefulWidget {
static const routeName = '/test-screen';
#override
_TestScreenState createState() => _TestScreenState();
}
class _TestScreenState extends State<TestScreen> {
final _form = GlobalKey<FormState>();
Future<void> _saveForm() async {
final isValid = _form.currentState.validate();
if (!isValid) {
return;
}
}
Widget _buildContainer(Widget child) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(10),
),
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
height: 200,
width: 300,
child: child,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Test',
style: Theme.of(context).textTheme.title,
),
automaticallyImplyLeading: false,
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
key: _form,
child: Column(
children: <Widget>[
TextFormField(
initialValue: '',
decoration: InputDecoration(labelText: 'Name'),
validator: (value) {
if (value.isEmpty) {
return 'Insert something';
}
return null;
},
),
TextFormField(
initialValue: '',
decoration: InputDecoration(labelText: 'Number'),
keyboardType: TextInputType.number,
validator: (value) {
if (int.tryParse(value) == null) {
return 'Insert a number';
}
return null;
},
),
SizedBox(height: 20),
_buildContainer(
ListView(
children: <Widget>[],
),
),
Text(
'Text-Test1',
textAlign: TextAlign.center,
),
Slider(
value: 1,
divisions: 3,
min: 0.0,
max: 3.0,
label: 'Test',
onChanged: (newValue) {},
),
SizedBox(
height: 20,
),
Text(
'Text-Test2',
textAlign: TextAlign.center,
),
Slider(
value: 3,
divisions: 4,
min: 0.0,
max: 4.0,
label: 'Nothing2',
onChanged: (newValue) {},
),
SizedBox(
height: 20,
),
Row(
children: <Widget>[
Text('RandomLabel'),
Spacer(),
Container(
width: 100,
child: TextFormField(
initialValue: '',
keyboardType: TextInputType.number,
validator: (value) {
if (int.tryParse(value) == null) {
return 'Insert a number';
}
return null;
},
),
),
],
),
SizedBox(
height: 20,
),
Text(
'Test 2',
textAlign: TextAlign.center,
),
_buildContainer(
ListView.builder(
itemCount: 0,
itemBuilder: (ctx, index) {
return ListTile(
title: Text('hello'),
subtitle: Text('world'),
);
},
),
),
TextFormField(
initialValue: '',
minLines: 4,
maxLines: 4,
decoration: InputDecoration(labelText: 'Text'),
validator: (value) {
if (value.isEmpty) {
return 'Insert something';
}
return null;
},
),
FlatButton.icon(
icon: Icon(Icons.check),
label: Text('Done'),
onPressed: () {
_saveForm();
},
),
],
),
),
),
),
);
}
}