Skip to content

Instantly share code, notes, and snippets.

@dhruvilp
Last active April 21, 2023 14:05
Show Gist options
  • Save dhruvilp/70394d6f4eafb952c348ae0c72f4ee4e to your computer and use it in GitHub Desktop.
Save dhruvilp/70394d6f4eafb952c348ae0c72f4ee4e to your computer and use it in GitHub Desktop.
TextField AutoComplete (using Overlay)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: OverlayExample(),
);
}
}
class CountriesField extends StatefulWidget {
@override
_CountriesFieldState createState() => _CountriesFieldState();
}
class _CountriesFieldState extends State<CountriesField> {
final FocusNode _focusNode = FocusNode();
OverlayEntry _overlayEntry;
final _countryController = TextEditingController();
List _itemsForDisplay = [];
List _items = ['USA','CANADA','INDIA','UK','S AFRICA'];
@override
void initState() {
super.initState();
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
this._overlayEntry = this._createOverlayEntry();
Overlay.of(context).insert(this._overlayEntry);
}
});
}
OverlayEntry _createOverlayEntry() {
RenderBox renderBox = context.findRenderObject();
var size = renderBox.size;
var offset = renderBox.localToGlobal(Offset.zero);
return OverlayEntry(
builder: (context) => Positioned(
left: offset.dx,
top: offset.dy + size.height + 5.0,
width: size.width,
child: Material(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemBuilder: (context, index) {
return _listItem(index);
},
itemCount: _itemsForDisplay.length,
),
),
)
);
}
_listItem(index) {
return ListTile(
title: Text(
_itemsForDisplay[index],
style: Theme.of(context).textTheme.headline6,
),
onTap: () {
setState((){
_countryController.text = _itemsForDisplay[index];
this._overlayEntry.remove();
});
},
);
}
@override
Widget build(BuildContext context) {
return TextField(
focusNode: this._focusNode,
controller: _countryController,
decoration: InputDecoration(
labelText: 'Country *',
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.cyan, width: 2.0),
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
),
onChanged: (text) {
text = text.toLowerCase();
setState(() {
_itemsForDisplay = _items.where((item) {
var kItem = item.toLowerCase();
return kItem.contains(text);
}).toList();
});
},
);
}
@override
void dispose() {
_countryController.dispose();
super.dispose();
}
}
class OverlayExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Overlay Example"),
actions: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Icon(Icons.notifications),
)
],
),
body: Padding(
padding: const EdgeInsets.all(25.0),
child: ListView(
children: [
CountriesField(),
],
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment