textfield_tags 2.0.2 textfield_tags: ^2.0.2 copied to clipboard
A text field that allows an input of tags inside the textfield
import 'package:flutter/material.dart';
import 'package:textfield_tags/textfield_tags.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.green),
home: const Home(),
);
}
}
class Home extends StatefulWidget {
const Home({Key key}) : super(key: key);
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
double _distanceToField;
TextfieldTagsController _controller;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_distanceToField = MediaQuery.of(context).size.width;
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
void initState() {
super.initState();
_controller = TextfieldTagsController();
}
static const List<String> _pickLanguage = <String>[
'c',
'c++',
'java',
'python',
'javascript',
'php',
'sql',
'yaml',
'gradle',
'xml',
'html',
'flutter',
'css',
'dockerfile'
];
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "wellcome",
home: Scaffold(
appBar: AppBar(
backgroundColor: const Color.fromARGB(255, 74, 137, 92),
centerTitle: true,
title: const Text('Enter a tag...'),
),
body: Column(
children: [
Autocomplete<String>(
optionsViewBuilder: (context, onSelected, options) {
return Container(
margin: const EdgeInsets.symmetric(
horizontal: 10.0, vertical: 4.0),
child: Align(
alignment: Alignment.topCenter,
child: Material(
elevation: 4.0,
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 200),
child: ListView.builder(
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final dynamic option = options.elementAt(index);
return TextButton(
onPressed: () {
onSelected(option);
},
child: Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 15.0),
child: Text(
'#$option',
textAlign: TextAlign.left,
style: const TextStyle(
color: Color.fromARGB(255, 74, 137, 92),
),
),
),
),
);
},
),
),
),
),
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
}
return _pickLanguage.where((String option) {
return option.contains(textEditingValue.text.toLowerCase());
});
},
onSelected: (String selectedTag) {
_controller.addTag = selectedTag;
},
fieldViewBuilder: (context, ttec, tfn, onFieldSubmitted) {
return TextFieldTags(
textEditingController: ttec,
focusNode: tfn,
textfieldTagsController: _controller,
initialTags: const [
'pick',
'your',
'favorite',
'programming',
'language',
],
textSeparators: const [' ', ','],
letterCase: LetterCase.normal,
validator: (String tag) {
if (tag == 'php') {
return 'No, please just no';
} else if (_controller.getTags.contains(tag)) {
return 'you already entered that';
}
return null;
},
inputfieldBuilder:
(context, tec, fn, error, onChanged, onSubmitted) {
return ((context, sc, tags, onTagDelete) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: TextField(
controller: tec,
focusNode: fn,
decoration: InputDecoration(
border: const UnderlineInputBorder(
borderSide: BorderSide(
color: Color.fromARGB(255, 74, 137, 92),
width: 3.0),
),
focusedBorder: const UnderlineInputBorder(
borderSide: BorderSide(
color: Color.fromARGB(255, 74, 137, 92),
width: 3.0),
),
helperText: 'Enter language...',
helperStyle: const TextStyle(
color: Color.fromARGB(255, 74, 137, 92),
),
hintText: _controller.hasTags ? '' : "Enter tag...",
errorText: error,
prefixIconConstraints: BoxConstraints(
maxWidth: _distanceToField * 0.74),
prefixIcon: tags.isNotEmpty
? SingleChildScrollView(
controller: sc,
scrollDirection: Axis.horizontal,
child: Row(
children: tags.map((String tag) {
return Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
color:
Color.fromARGB(255, 74, 137, 92),
),
margin:
const EdgeInsets.only(right: 10.0),
padding: const EdgeInsets.symmetric(
horizontal: 10.0, vertical: 4.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
InkWell(
child: Text(
'#$tag',
style: const TextStyle(
color: Colors.white),
),
onTap: () {
//print("$tag selected");
},
),
const SizedBox(width: 4.0),
InkWell(
child: const Icon(
Icons.cancel,
size: 14.0,
color: Color.fromARGB(
255, 233, 233, 233),
),
onTap: () {
onTagDelete(tag);
},
)
],
),
);
}).toList()),
)
: null,
),
onChanged: onChanged,
onSubmitted: onSubmitted,
),
);
});
},
);
},
),
ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
const Color.fromARGB(255, 74, 137, 92),
),
),
onPressed: () {
_controller.clearTags();
},
child: const Text('CLEAR TAGS'),
),
],
),
),
);
}
}