skip to Main Content

I have, which is probably a simple error. I’m using a TextField and created a custom widget.

    class NoteField extends StatefulWidget {
  NoteField({Key? key, required this.n}) : super(key: key);
  String n;

  @override
  State<NoteField> createState() => _NoteFieldState();
}

class _NoteFieldState extends State<NoteField> {
  @override
  Widget build(BuildContext context) {
    return TextField(
      maxLength: 40,
      onChanged: (String value) {
        widget.n = value;
        print(widget.n);
      },
      decoration: InputDecoration(
        border: OutlineInputBorder(
            borderSide: BorderSide(
          color: Theme.of(context).primaryColor,
        )),
        hintText: 'Enter a label for your visit',
      ),
    );
  }

So when I use this widget, I’ve created a String _note and I pass this to the widget.

NoteField(n: _note),

However, I’m getting blank. When I type I can see n updating from the print statement but when I try and print _note when I press a button, it’s showing as blank.

3

Answers


  1. You can either use a TextEditingController or in your onChanged you need to wrap the assignment in a

    
    SetState(() {
     widget.n = value
    })
    
    
    Login or Signup to reply.
  2. You should use a TextEditingController to keep the state of your values and retrieve it in parents widget.

    There is multiple solution to manage the state, one of them using setState and keys is the following:

    You assign a GlobalKey to retrieve your child stateful widget. You create a TextEditingController that manages the initial value and that will hold your textfield data.
    Finally you use the key to access the state of your child widget.

    class TextFieldPage extends StatelessWidget {
      TextFieldPage({super.key});
    
      final GlobalKey<NoteFieldState> noteFieldKey = GlobalKey<NoteFieldState>();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
          child: Column(
            children: [
              NoteField(
                key: noteFieldKey,
              ),
              ElevatedButton(
                  onPressed: () {
                    print(noteFieldKey.currentState!.controller!.text);
                  },
                  child: Text('Print textfield value')),
            ],
          ),
        ));
      }
    }
    
    class NoteField extends StatefulWidget {
      const NoteField({Key? key, this.initialString}) : super(key: key);
      final String? initialString;
    
      @override
      State<NoteField> createState() => NoteFieldState();
    }
    
    class NoteFieldState extends State<NoteField> {
      late TextEditingController? controller;
    
      @override
      void initState() {
        controller = TextEditingController(text: widget.initialString);
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return TextField(
          controller: controller,
          maxLength: 40,
          decoration: InputDecoration(
            border: OutlineInputBorder(
                borderSide: BorderSide(
              color: Theme.of(context).primaryColor,
            )),
            hintText: 'Enter a label for your visit',
          ),
        );
      }
    }
    
    

    EDIT

    You can always pass a callback to your widget to update the value you are passing to the TextField widget:

    import 'package:flutter/material.dart';
    import 'package:flutter/src/widgets/framework.dart';
    import 'package:flutter/src/widgets/placeholder.dart';
    
    class TextFieldPage extends StatefulWidget {
      TextFieldPage({super.key});
    
      @override
      State<TextFieldPage> createState() => _TextFieldPageState();
    }
    
    class _TextFieldPageState extends State<TextFieldPage> {
      String data = '';
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: Center(
          child: Column(
            children: [
              NoteField(
                  callback: (value) => setState(() => data = value)),
              ElevatedButton(
                  onPressed: () {
                    print(data);
                  },
                  child: Text('Print textfield value')),
            ],
          ),
        ));
      }
    }
    
    class NoteField extends StatefulWidget {
      const NoteField({Key? key, required this.callback}) : super(key: key);
      final Function callback;
    
      @override
      State<NoteField> createState() => NoteFieldState();
    }
    
    class NoteFieldState extends State<NoteField> {
      @override
      Widget build(BuildContext context) {
        return TextField(
          onChanged: (value) => widget.callback(value),
          maxLength: 40,
          decoration: InputDecoration(
            border: OutlineInputBorder(
                borderSide: BorderSide(
              color: Theme.of(context).primaryColor,
            )),
            hintText: 'Enter a label for your visit',
          ),
        );
      }
    }
    
    
    Login or Signup to reply.
  3. Instead of passing a string pass the TextEditingController to the class.

    class NoteField extends StatefulWidget {
      NoteField({Key? key, required this.n}) : super(key: key);
      TextEditingController n;
    
      @override
      State<NoteField> createState() => _NoteFieldState();
    }
    
    class _NoteFieldState extends State<NoteField> {
      @override
      Widget build(BuildContext context) {
        return TextField(
          controller: n,
          maxLength: 40,
          decoration: InputDecoration(
            border: OutlineInputBorder(
                borderSide: BorderSide(
              color: Theme.of(context).primaryColor,
            )),
            hintText: 'Enter a label for your visit',
          ),
        );
      }
    

    Use

    print(controller.text);
    

    From the other classs. Here controller is the TextEditingController that you passed to the NoteField class

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search