Say I've created a file info_card.dart that I want to use to get the name of a user with the following code:-

import 'package:flutter/material.dart';

class InfoCard extends StatefulWidget {
  const InfoCard({ Key? key }) : super(key: key);

  @override
  State<InfoCard> createState() => _InfoCardState();
}

class _InfoCardState extends State<InfoCard> {

  final _nameController = TextEditingController();

  @override
  void dispose() {
    _nameController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _nameController
    );
  }
}

And then I create a completely different file, home_page.dart for example:-

    import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  const HomePage({ Key? key }) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: InfoCard(),
    );
  }
}

How would I access the text controller within the InfoCard() widget, and say store it in a variable so that I could write it to a database? I'm really struggling with this as simply trying to use InfoCard()._nameController doesn't seem to work.


Solution 1: Ivo

You could create the controller in the home page instead and pass it to the infocard. for example:

class HomePage extends StatefulWidget {
  const HomePage({ Key? key }) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final _nameController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: InfoCard(controller: _nameController ),
    );
  }

  @override
  void dispose() {
    _nameController.dispose();
    super.dispose();
  }
}

and

class InfoCard extends StatefulWidget {
  final TextEditingController  controller;

  const InfoCard({ Key? key, required this.controller}) : super(key: key);

  @override
  State<InfoCard> createState() => _InfoCardState();
}

class _InfoCardState extends State<InfoCard> {

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: widget.controller
    );
  }
}


Solution 2: sharbel okzan

There are many ways to achieve that in Flutter, the simplest thing you can do:

  1. Instead of creating the controller inside InfoCard, inject it to it by its constructor. So your file will look like this:

class InfoCard extends StatefulWidget {
  const InfoCard( this._nameController , { Key? key,}) : super(key: key);
  final TextEditingController _nameController;

  @override
  State<InfoCard> createState() => _InfoCardState();
}

class _InfoCardState extends State<InfoCard> {

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: widget._nameController,
    );
  }
}
  1. Create a controller in HomePage and pass it to InfoCard, thus, you'll have a reference to that controller in HomePage. So your file will look like this:
class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  TextEditingController _infoCardController = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: InfoCard(_infoCardController),
    );
  }
}
  1. Now pass that controller reference _infoCardController wherever you need it, and use simply as
print(_infoCardController.text)


Solution 3: Udit Shrimali

Here i Solve this problem you can follow these steps: just click the button and check the controller result in the console window HomePage Code:

 class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  TextEditingController textController = TextEditingController();
  void getText(){
print("entered text "+ textController.text);
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
        body: Center(child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            InfoCard(textController),
            ElevatedButton(onPressed: getText, child: Text("Press Here !")),
          ],
        )),
    );
  }
}

InfoCard Page:

import 'package:flutter/material.dart';

class InfoCard extends StatefulWidget {
  final TextEditingController textController ;
  const InfoCard(@required this.textController);

  @override
  State<InfoCard> createState() => _InfoCardState();
}

class _InfoCardState extends State<InfoCard> {

  // final _nameController = TextEditingController();

  @override
  void dispose() {
    widget.textController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.grey,
      child: TextField(
          controller: widget.textController
      ),
    );
  }
}