Flutter Custom TextField | Focus Node, Next Node and onTap Function

Flutter Custom TextField includes features like focus node, next node, onTap function, 

void main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    final TextEditingController _addressController = TextEditingController();
    final TextEditingController _contactPersonNameController = TextEditingController();
    final TextEditingController _contactPersonNumberController = TextEditingController();
    final FocusNode _addressNode = FocusNode();
    final FocusNode _nameNode = FocusNode();
    final FocusNode _numberNode = FocusNode();
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primaryColor: Colors.blue,
        fontFamily: "Lato",
      ),
      home: Scaffold(
        backgroundColor: Colors.white,
        body: Center(
        child:  Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            MyTextField(
              hintText: 'Delivery address',
              inputType: TextInputType.streetAddress,
              focusNode: _addressNode,
              nextFocus: _nameNode,
              controller: _addressController,
            ),
            MyTextField(
              hintText: 'Person name',
              inputType: TextInputType.name,
              focusNode: _nameNode,
              nextFocus: _numberNode,
              controller: _contactPersonNameController,
            )
          ],
        ),
        ),
      ),
    );
  }
}
final robotoRegular = TextStyle(
  fontFamily: 'Roboto',
  fontWeight: FontWeight.w400,
  fontSize: 15,
);
class MyTextField extends StatefulWidget {
  final String hintText;
  final TextEditingController controller;
  final FocusNode focusNode;
  final FocusNode nextFocus;
  final TextInputType inputType;
  final TextInputAction inputAction;
  final int maxLines;
  final bool isPassword;
  final VoidCallback? onTap;
  final VoidCallback? onChanged;
  final VoidCallback? onSubmit;
  final bool isEnabled;
  final TextCapitalization capitalization;
  final Color? fillColor;
  final bool autoFocus;
  final GlobalKey<FormFieldState<String>>? key;

  MyTextField(
      {this.hintText = '',
        required this.controller,
        required this.focusNode,
        required this.nextFocus,
        this.isEnabled = true,
        this.inputType = TextInputType.text,
        this.inputAction = TextInputAction.next,
        this.maxLines = 1,
        this.onSubmit,
        this.onChanged,
        this.capitalization = TextCapitalization.none,
        this.onTap,
        this.fillColor,
        this.isPassword = false,
        this.autoFocus = false,
        this.key});

  @override
  _MyTextFieldState createState() => _MyTextFieldState();
}

class _MyTextFieldState extends State<MyTextField> {
  bool _obscureText = true;

  @override
  Widget build(BuildContext context) {
    return TextField(
      key: widget.key,
      maxLines: widget.maxLines,
      controller: widget.controller,
      focusNode: widget.focusNode,
      style: robotoRegular,
      textInputAction: widget.inputAction,
      keyboardType: widget.inputType,
      cursorColor: Theme.of(context).primaryColor,
      textCapitalization: widget.capitalization,
      enabled: widget.isEnabled,
      autofocus: widget.autoFocus,
      //onChanged: widget.isSearch ? widget.languageProvider.searchLanguage : null,
      obscureText: widget.isPassword ? _obscureText : false,
     // inputFormatters: widget.inputType == TextInputType.phone ? <TextInputFormatter>[FilteringTextInputFormatter.allow(RegExp('[0-9+]'))] : null,
      decoration: InputDecoration(
        hintText: widget.hintText,
        isDense: true,
        filled: true,
        fillColor: widget.fillColor != null ? widget.fillColor : Theme.of(context).cardColor,
        border: OutlineInputBorder(borderRadius: BorderRadius.circular(10), borderSide: BorderSide.none),
        hintStyle: robotoRegular.copyWith(color: Theme.of(context).hintColor),
        suffixIcon: widget.isPassword ? IconButton(
          icon: Icon(_obscureText ? Icons.visibility_off : Icons.visibility, color: Theme.of(context).hintColor.withOpacity(0.3)),
          onPressed: _toggle,
        ) : null,
      ),
      onTap: widget.onTap,
      onSubmitted: (text) => widget.nextFocus != null ? FocusScope.of(context).requestFocus(widget.nextFocus)
          : widget.onSubmit != null ? widget.onSubmit! : null,
     // onChanged: widget.onChanged,
    );
  }

  void _toggle() {
    setState(() {
      _obscureText = !_obscureText;
    });
  }
}

Recent posts