I tried to create a TextFormField component with chip and label text.
code:
class BasicChipTextField extends StatelessWidget {
const BasicChipTextField(
{Key? key,
this.testKey,
this.label,
this.hintText,
this.suffixIcon,
this.controller,
this.textLength,
this.inputFormatters,
this.initialValue,
this.keyboardType,
this.copyPasteOption,
this.onChanged,
this.focusNode,
this.autoValidateMode,
this.onTap,
required this.isDifferentlyAbledSelected,
required this.selected,
required this.validator,
required this.readOnly,
required this.obSecureText,
required this.textCapitalization})
: super(key: key);
final Key? testKey;
final bool? copyPasteOption;
final bool readOnly;
final bool isDifferentlyAbledSelected;
final LabelWithMandatoryStar? label;
final TextCapitalization textCapitalization;
final List<TextInputFormatter>? inputFormatters;
final String? hintText;
final String? initialValue;
final bool obSecureText;
final BasicIcon? suffixIcon;
final TextInputType? keyboardType;
final TextEditingController? controller;
final int? textLength;
final String? Function(String?)? validator;
final void Function(String)? onChanged;
final FocusNode? focusNode;
final AutovalidateMode? autoValidateMode;
final List<BottomNavListItemDto>? selected;
final void Function()? onTap;
@override
Widget build(BuildContext context) {
return StatefulBuilder(builder: (context, setState) {
return TextFormField(
key: testKey,
onTap: onTap,
onChanged: onChanged,
autovalidateMode: autoValidateMode,
focusNode: focusNode,
enableInteractiveSelection: copyPasteOption,
readOnly: readOnly,
keyboardType: keyboardType,
textCapitalization: textCapitalization,
inputFormatters: inputFormatters,
maxLength: textLength,
validator: validator,
style: const TextStyle(
fontSize: 14, color: AppColor.black, fontWeight: AppFont.fontWeightRegular
// Reference to the foundation layer
),
initialValue: initialValue,
controller: controller,
obscureText: obSecureText,
decoration: InputDecoration(
alignLabelWithHint: true,
filled: true,
fillColor: AppColor.white,
counterText: "",
prefixIcon: prefixIcon(selected, setState),
label: label,
hintText: hintText,
suffixIcon: suffixIcon,
hintStyle: const TextStyle(color: AppColor.hintColor),
contentPadding: const EdgeInsets.only(bottom: 16, top: 16, left: 15, right: 15),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: AppColor.textFieldBorderColor, width: 0),
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(
color: AppColor.textFieldBorderColor,
width: 0,
),
),
errorBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 0,
color: AppColor.error,
)),
focusedErrorBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 0,
color: AppColor.error,
),
),
errorStyle: const TextStyle(
height: 0,
color: AppColor.error,
),
));
});
}
prefixIcon(List<BottomNavListItemDto>? selected, StateSetter setState) {
List<BottomNavListItemDto>? selectedTemp = [];
for(var item in selected!){
if(item.isSelected!){
selectedTemp.add(item);
}
}
if (selectedTemp.length < 1) {
return null;
} else {
return Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Wrap(
spacing: 5,
children: selectedTemp.map(
(item) {
return Chip(
backgroundColor: AppColor.chipGrey,
avatar: const Icon(Icons.album_outlined, size: 20),
elevation: 0,
shadowColor: Colors.teal,
label: Text(item.name!, style: TextStyle(color: AppColor.black)),
onDeleted: () {
setState(() {
for(var removedItem in selected){
if(removedItem.id == item.id){
removedItem.isSelected = false;
}
}
selectedTemp.remove(item);
});
});
},
).toList(),
),
);
}
}
}
The above code makes the field like this:
position of the label is changes. Anyone have any idea about this?? I need a TextFormField with exact positioned label. This code doesn't meet the requirement.
Padding( padding: const EdgeInsets.only(left: 10, right: 10), child: Wrap( spacing: 5, children: selectedTemp.map( (item) { return Chip( backgroundColor: AppColor.chipGrey, avatar: const Icon(Icons.album_outlined, size: 20), elevation: 0, shadowColor: Colors.teal, label: Text(item.name!, style: TextStyle(color: AppColor.black)), onDeleted: () { setState(() { for(var removedItem in selected){ if(removedItem.id == item.id){ removedItem.isSelected = false; } } selectedTemp.remove(item); }); }); }, ).toList(), ), );
this is the chip code.
After a long time of search I got a perfect answer for this :
isCollapsed: true
by adding the above code to decoration and changed prefixIcon to prefix.