buildTextField method
This function Build and returns individual TextField item.
- Requires a build context
- Requires Int position of the field
Implementation
Widget buildTextField(BuildContext context, int index) {
FocusNode? focusNode = _focusNodes[index];
TextEditingController? textEditingController = _textControllers[index];
// if focus node doesn't exist, create it.
if (focusNode == null) {
_focusNodes[index] = FocusNode();
focusNode = _focusNodes[index];
focusNode?.addListener((() => handleFocusChange(index)));
}
if (textEditingController == null) {
_textControllers[index] = TextEditingController();
textEditingController = _textControllers[index];
}
final isLast = index == widget.length - 1;
InputBorder getBorder(Color color) {
final colorOrError =
widget.hasError ? _otpFieldStyle.errorBorderColor : color;
return widget.fieldStyle == FieldStyle.box
? OutlineInputBorder(
borderSide: BorderSide(color: colorOrError),
borderRadius: BorderRadius.circular(widget.outlineBorderRadius),
)
: UnderlineInputBorder(borderSide: BorderSide(color: colorOrError));
}
return Container(
width: widget.fieldWidth,
margin: EdgeInsets.only(
right: isLast ? 0 : widget.spaceBetween,
),
child: TextField(
controller: _textControllers[index],
keyboardType: widget.keyboardType,
textCapitalization: widget.textCapitalization,
textAlign: TextAlign.center,
style: widget.style,
inputFormatters: widget.inputFormatter,
maxLength: 1,
focusNode: _focusNodes[index],
obscureText: widget.obscureText,
decoration: InputDecoration(
isDense: widget.isDense,
filled: true,
fillColor: _otpFieldStyle.backgroundColor,
counterText: "",
contentPadding: widget.contentPadding,
border: getBorder(_otpFieldStyle.borderColor),
focusedBorder: getBorder(_otpFieldStyle.focusBorderColor),
enabledBorder: getBorder(_otpFieldStyle.enabledBorderColor),
disabledBorder: getBorder(_otpFieldStyle.disabledBorderColor),
errorBorder: getBorder(_otpFieldStyle.errorBorderColor),
focusedErrorBorder: getBorder(_otpFieldStyle.errorBorderColor),
errorText: null,
// to hide the error text
errorStyle: const TextStyle(height: 0, fontSize: 0),
),
onChanged: (String str) {
if (str.length > 1) {
_handlePaste(str);
return;
}
// Check if the current value at this position is empty
// If it is move focus to previous text field.
if (str.isEmpty) {
if (index == 0) return;
_focusNodes[index]!.unfocus();
_focusNodes[index - 1]!.requestFocus();
}
// Update the current pin
setState(() {
_pin[index] = str;
});
// Remove focus
if (str.isNotEmpty) _focusNodes[index]!.unfocus();
// Set focus to the next field if available
if (index + 1 != widget.length && str.isNotEmpty) {
FocusScope.of(context).requestFocus(_focusNodes[index + 1]);
}
String currentPin = _getCurrentPin();
// if there are no null values that means otp is completed
// Call the `onCompleted` callback function provided
if (!_pin.contains(null) &&
!_pin.contains('') &&
currentPin.length == widget.length) {
widget.onCompleted?.call(currentPin);
}
// Call the `onChanged` callback function
widget.onChanged!(currentPin);
},
),
);
}