Introduction:
Implementing a Dropdown TextField in Flutter allows users to select an option from a dropdown list or enter custom text. This provides a flexible input method for selecting or entering data. The dropdown_textfield
package simplifies the implementation of this feature. This tutorial will guide you through implementing a Dropdown TextField using the dropdown_textfield
package with more details.
Content:
Step 1: Add the dependency:
Include the dropdown_textfield
package in your pubspec.yaml
file:
dependencies:
dropdown_textfield: ^1.0.0
Run flutter pub get
to install the package.
Step 2: Import the package:
Import the dropdown_textfield
package in your Dart file:
import 'package:flutter/material.dart';
import 'package:dropdown_textfield/dropdown_textfield.dart';
Step 3: Create a DropdownTextField widget:
Define a stateful widget and implement the DropdownTextField
widget with your desired options:
class DropdownTextFieldScreen extends StatefulWidget {
@override
_DropdownTextFieldScreenState createState() =>
_DropdownTextFieldScreenState();
}
class _DropdownTextFieldScreenState extends State<DropdownTextFieldScreen> {
final List<String> _options = ['Option 1', 'Option 2', 'Option 3'];
String _selectedOption = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dropdown TextField Example'),
),
body: Center(
child: DropdownTextField(
items: _options,
hintText: 'Select or type an option',
onChanged: (value) {
setState(() {
_selectedOption = value;
});
},
),
),
);
}
}
In this example, the DropdownTextField
widget is created with a list of options and a callback to update the selected option. Users can select an option from the dropdown list or enter custom text.
Step 4: Run the app:
Run your Flutter app to see the dropdown text field in action. You should see a text field with a dropdown arrow that allows you to select an option from the list or enter custom text.
Sample Code:
// ignore_for_file: prefer_const_constructors
import 'package:dropdown_textfield/dropdown_textfield.dart';
import 'package:flutter/material.dart';
class DroupdownTextfild extends StatefulWidget {
const DroupdownTextfild({Key? key}) : super(key: key);
@override
State<DroupdownTextfild> createState() => _DroupdownTextfildState();
}
class _DroupdownTextfildState extends State<DroupdownTextfild> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
FocusNode searchFocusNode = FocusNode();
FocusNode textFieldFocusNode = FocusNode();
late SingleValueDropDownController _cnt;
late MultiValueDropDownController _cntMulti;
@override
void initState() {
_cnt = SingleValueDropDownController();
_cntMulti = MultiValueDropDownController();
super.initState();
}
@override
void dispose() {
_cnt.dispose();
_cntMulti.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 30,
),
const Text(
"Single selection dropdown with search option",
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
height: 10,
),
DropDownTextField(
textFieldDecoration: InputDecoration(
hintText: ' select',
prefixIcon: Icon(Icons.person),
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
// Clear the text field
},
),
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1.0),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
filled: true,
fillColor: Colors.grey.shade200,
contentPadding: EdgeInsets.all(16.0),
),
// initialValue: "name4",
controller: _cnt,
clearOption: true,
// enableSearch: true,
// dropdownColor: Colors.green,
searchDecoration: const InputDecoration(hintText: "enter your custom hint text here"),
validator: (value) {
if (value == null) {
return "Required field";
} else {
return null;
}
},
dropDownItemCount: 6,
dropDownList: const [
DropDownValueModel(name: 'name1', value: "value1"),
DropDownValueModel(
name: 'name2',
value: "value2",
toolTipMsg: "DropDownButton is a widget that we can use to select one unique value from a set of values"),
DropDownValueModel(name: 'name3', value: "value3"),
DropDownValueModel(
name: 'name4',
value: "value4",
toolTipMsg: "DropDownButton is a widget that we can use to select one unique value from a set of values"),
],
onChanged: (val) {},
),
const SizedBox(
height: 100,
),
const Text(
"Single selection dropdown with search option",
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
height: 10,
),
DropDownTextField(
textFieldDecoration: InputDecoration(
hintText: ' select',
prefixIcon: Icon(Icons.person),
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
// Clear the text field
},
),
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1.0),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
filled: true,
fillColor: Colors.grey.shade200,
contentPadding: EdgeInsets.all(16.0),
),
clearOption: false,
textFieldFocusNode: textFieldFocusNode,
searchFocusNode: searchFocusNode,
// searchAutofocus: true,
dropDownItemCount: 8,
searchShowCursor: false,
enableSearch: true,
searchKeyboardType: TextInputType.number,
dropDownList: const [
DropDownValueModel(name: 'name1', value: "value1"),
DropDownValueModel(
name: 'name2',
value: "value2",
toolTipMsg: "DropDownButton is a widget that we can use to select one unique value from a set of values"),
DropDownValueModel(name: 'name3', value: "value3"),
DropDownValueModel(
name: 'name4',
value: "value4",
toolTipMsg: "DropDownButton is a widget that we can use to select one unique value from a set of values"),
],
onChanged: (val) {},
),
const SizedBox(
height: 100,
),
const Text(
"multi selection dropdown",
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
height: 20,
),
DropDownTextField.multiSelection(
textFieldDecoration: InputDecoration(
hintText: ' select',
prefixIcon: Icon(Icons.person),
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
// Clear the text field
},
),
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1.0),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
filled: true,
fillColor: Colors.grey.shade200,
contentPadding: EdgeInsets.all(16.0),
),
// controller: _cntMulti,
displayCompleteItem: true,
initialValue: const ["name1", "name2", "name8", "name3"],
dropDownList: const [
DropDownValueModel(name: 'name1', value: "value1"),
DropDownValueModel(
name: 'name2',
value: "value2",
toolTipMsg: "DropDownButton is a widget that we can use to select one unique value from a set of values"),
DropDownValueModel(name: 'name3', value: "value3"),
DropDownValueModel(
name: 'name4',
value: "value4",
toolTipMsg: "DropDownButton is a widget that we can use to select one unique value from a set of values"),
],
onChanged: (val) {
setState(() {});
},
),
const SizedBox(
height: 100,
),
const Text(
"Single selection dropdown",
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
height: 20,
),
DropDownTextField(
textFieldDecoration: InputDecoration(
hintText: ' select',
prefixIcon: Icon(Icons.person),
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
// Clear the text field
},
),
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 1.0),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2.0),
),
filled: true,
fillColor: Colors.grey.shade200,
contentPadding: EdgeInsets.all(16.0),
),
// initialValue: "name4",
listSpace: 20,
listPadding: ListPadding(top: 20),
enableSearch: true,
validator: (value) {
if (value == null) {
return "Required field";
} else {
return null;
}
},
dropDownList: const [
DropDownValueModel(name: 'name1', value: "value1"),
DropDownValueModel(name: 'name2', value: "value2"),
DropDownValueModel(name: 'name3', value: "value3"),
DropDownValueModel(name: 'name4', value: "value4"),
],
listTextStyle: const TextStyle(color: Colors.red),
dropDownItemCount: 8,
onChanged: (val) {},
),
const SizedBox(
height: 50,
)
],
),
),
),
],
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
setState(() {});
},
label: const Text("Submit"),
),
);
}
}
class TestPage2 extends StatefulWidget {
const TestPage2({Key? key}) : super(key: key);
@override
State<TestPage2> createState() => _TestPage2State();
}
class _TestPage2State extends State<TestPage2> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
FocusNode searchFocusNode = FocusNode();
FocusNode textFieldFocusNode = FocusNode();
late SingleValueDropDownController _cnt;
late MultiValueDropDownController _cntMulti;
final formKey = GlobalKey<FormState>();
@override
void initState() {
_cnt = SingleValueDropDownController();
_cntMulti = MultiValueDropDownController();
super.initState();
}
@override
void dispose() {
_cnt.dispose();
_cntMulti.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 50,
),
const Text(
"Single selection dropdown with search option",
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
height: 20,
),
Form(
key: formKey,
child: DropDownTextField(
// initialValue: "name4",
// readOnly: false,
controller: _cnt,
clearOption: true,
keyboardType: TextInputType.number,
autovalidateMode: AutovalidateMode.always,
clearIconProperty: IconProperty(color: Colors.green),
searchDecoration: const InputDecoration(hintText: "enter your custom hint text here"),
validator: (value) {
if (value == null || value.isEmpty) {
return "Required field";
} else {
return null;
}
},
dropDownItemCount: 6,
dropDownList: const [
DropDownValueModel(name: 'name1', value: "value1"),
DropDownValueModel(
name: 'name2',
value: "value2",
toolTipMsg: "DropDownButton is a widget that we can use to select one unique value from a set of values"),
DropDownValueModel(name: 'name3', value: "value3"),
DropDownValueModel(
name: 'name4',
value: "value4",
toolTipMsg: "DropDownButton is a widget that we can use to select one unique value from a set of values"),
],
onChanged: (val) {},
),
),
],
),
),
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
formKey.currentState!.validate();
},
label: const Text("Submit"),
),
);
}
}
Output:
Conclusion:
By following these steps, you can easily implement a Dropdown TextField in Flutter using the dropdown_textfield
package. This provides a user-friendly input method for selecting or entering data in your app.