Last active
April 21, 2023 14:05
-
-
Save dhruvilp/70394d6f4eafb952c348ae0c72f4ee4e to your computer and use it in GitHub Desktop.
TextField AutoComplete (using Overlay)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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