Last active
May 2, 2020 22:35
-
-
Save sayhicoelho/cda5f71879d0d6186ee4b13b9e16ae63 to your computer and use it in GitHub Desktop.
Flutter Searchable Input
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'; | |
import './custom_searchable_dialog.dart'; | |
import './custom_text_field.dart'; | |
class CustomSearchableItem<T> { | |
final String label; | |
final T value; | |
CustomSearchableItem({ | |
@required this.label, | |
@required this.value, | |
}); | |
@override | |
String toString() => 'CustomSearchableItem(label: $label, value: $value)'; | |
} | |
class CustomSearchable<T> extends StatefulWidget { | |
final Function(CustomSearchableItem<T>) onChanged; | |
final CustomSearchableItem<T> value; | |
final List<CustomSearchableItem<T>> items; | |
final String label; | |
final String hintText; | |
final String searchHint; | |
final bool enabled; | |
CustomSearchable({ | |
Key key, | |
@required this.onChanged, | |
@required this.value, | |
@required this.items, | |
@required this.label, | |
this.hintText = 'Selecione', | |
this.searchHint = 'Pesquisar', | |
this.enabled = true, | |
}) : super(key: key); | |
@override | |
_CustomSearchableState createState() => _CustomSearchableState<T>(); | |
} | |
class _CustomSearchableState<T> extends State<CustomSearchable<T>> { | |
final _controller = TextEditingController(); | |
@override | |
Widget build(BuildContext context) { | |
if (widget.value == null) { | |
_controller.clear(); | |
} | |
return CustomTextField( | |
controller: _controller, | |
label: widget.label, | |
hintText: widget.hintText, | |
enabled: widget.enabled, | |
readonly: true, | |
onTap: () { | |
showDialog( | |
context: context, | |
builder: (context) => SimpleDialog( | |
contentPadding: const EdgeInsets.all(0.0), | |
children: <Widget>[ | |
CustomSearchableDialog<T>( | |
items: widget.items, | |
onChanged: (v) { | |
widget.onChanged(v); | |
_controller.text = v.label; | |
Navigator.of(context).pop(); | |
}, | |
searchHint: widget.searchHint, | |
), | |
], | |
) | |
); | |
}, | |
); | |
} | |
} |
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'; | |
import './custom_searchable.dart'; | |
class CustomSearchableDialog<T> extends StatefulWidget { | |
final Function(CustomSearchableItem<T>) onChanged; | |
final List<CustomSearchableItem<T>> items; | |
final String searchHint; | |
const CustomSearchableDialog({ | |
Key key, | |
@required this.onChanged, | |
@required this.items, | |
@required this.searchHint, | |
}) : super(key: key); | |
@override | |
_CustomSearchableDialogState createState() => _CustomSearchableDialogState<T>(); | |
} | |
class _CustomSearchableDialogState<T> extends State<CustomSearchableDialog<T>> { | |
var _searched = <CustomSearchableItem<T>>[]; | |
@override | |
void initState() { | |
super.initState(); | |
_searched = [...widget.items]; | |
} | |
void _search(String value) { | |
var result = widget.items.where((item) => | |
item.label.toLowerCase().contains(value.toLowerCase())).toList(); | |
_searched.clear(); | |
setState(() { | |
_searched = [...result]; | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
mainAxisSize: MainAxisSize.min, | |
children: <Widget>[ | |
Padding( | |
padding: const EdgeInsets.only(left: 16.0, top: 16.0, right: 16.0), | |
child: Text(widget.searchHint), | |
), | |
const SizedBox(height: 8.0,), | |
TextField( | |
onChanged: _search, | |
decoration: InputDecoration( | |
contentPadding: const EdgeInsets.all(16.0), | |
prefixIcon: Icon(Icons.search), | |
filled: false, fillColor: Colors.red | |
), | |
), | |
Container( | |
width: double.maxFinite, | |
height: 200.0, | |
child: ListView.builder( | |
itemCount: _searched.length, | |
itemBuilder: (context, index) => InkWell( | |
child: Padding( | |
padding: const EdgeInsets.all(16.0), | |
child: Text(_searched[index].label), | |
), | |
onTap: () { | |
widget.onChanged(_searched[index]); | |
}, | |
), | |
shrinkWrap: true, | |
), | |
), | |
], | |
); | |
} | |
} |
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'; | |
import './config/theme.dart'; | |
class CustomTextField extends StatelessWidget { | |
final TextEditingController controller; | |
final String label; | |
final bool enabled; | |
final bool obscureText; | |
final Function(String) onFieldSubmitted; | |
final String hintText; | |
final TextInputAction textInputAction; | |
final TextInputType keyboardType; | |
final FocusNode focusNode; | |
final Function onTap; | |
final Function(String) onChanged; | |
final bool readonly; | |
const CustomTextField({ | |
Key key, | |
@required this.controller, | |
@required this.label, | |
this.enabled = true, | |
this.obscureText = false, | |
this.onFieldSubmitted, | |
this.hintText, | |
this.textInputAction, | |
this.keyboardType, | |
this.focusNode, | |
this.onTap, | |
this.onChanged, | |
this.readonly = false, | |
}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
const borderWidth = 1.5; | |
return Column( | |
children: <Widget>[ | |
Text( | |
label.toUpperCase(), | |
style: TextStyle( | |
fontSize: 16.0, | |
color: enabled | |
? CustomTheme.PRIMARY_COLOR | |
: CustomTheme.PRIMARY_LIGHT_COLOR, | |
), | |
), | |
const SizedBox(height: 8.0,), | |
InkWell( | |
onTap: onTap != null && enabled ? () {} : null, | |
child: TextFormField( | |
controller: controller, | |
enabled: enabled, | |
obscureText: obscureText, | |
keyboardType: keyboardType, | |
textInputAction: textInputAction, | |
onFieldSubmitted: onFieldSubmitted, | |
focusNode: focusNode, | |
onChanged: onChanged, | |
readOnly: readonly, | |
onTap: onTap, | |
decoration: InputDecoration( | |
hintText: hintText, | |
contentPadding: const EdgeInsets.all(16.0), | |
border: OutlineInputBorder( | |
borderRadius: BorderRadius.zero, | |
), | |
enabledBorder: OutlineInputBorder( | |
borderSide: BorderSide( | |
width: borderWidth, | |
color: CustomTheme.PRIMARY_COLOR, | |
), | |
borderRadius: BorderRadius.zero, | |
), | |
disabledBorder: OutlineInputBorder( | |
borderSide: BorderSide( | |
width: borderWidth, | |
color: CustomTheme.PRIMARY_LIGHT_COLOR, | |
), | |
borderRadius: BorderRadius.zero, | |
), | |
focusedBorder: OutlineInputBorder( | |
borderSide: BorderSide( | |
width: borderWidth, | |
color: CustomTheme.PRIMARY_COLOR, | |
), | |
borderRadius: BorderRadius.zero, | |
), | |
), | |
), | |
) | |
], | |
); | |
} | |
} |
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 'dart:ui'; | |
class CustomTheme { | |
static const PRIMARY_COLOR = Color(0xFF2957A4); | |
static const PRIMARY_LIGHT_COLOR = Color(0x772957A4); | |
static const SECONDARY_COLOR = Color(0xFF354F77); | |
static const LIGHT_COLOR = Color(0xFFF2F2F2); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment