Matěj Michálek
Matěj Michálek

Reputation: 53

Flutter - How to access TextEditingController in other widget?

I have a TextField in my main.dart with controller called textcontroller. In other widget (button.dart) i have a button. If i press that button it should set text of a Text widget in my main.dart to the text of the TextField. Just do the same as the first button in my main.dart. How can i access this TextEditingController from other widget (file)?

Here is video of my app for better understanding. https://streamable.com/xi0dn1

Here is my full code of main.dart

import 'button.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyHomePage(),
    );
  }
}

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

  final String title;

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

class MyHomePageState extends State<MyHomePage> {
  String var1 = "text1";
  TextEditingController textController = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("My app"),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            TextField(
              controller: textController,
            ),
            RaisedButton(
              child: Text("button in the same widget"),
              onPressed: () {
                setState(() {
                  var1 = textController.text;
                });
              },
            ),
            Text(var1),
            Button2(),
          ],
        ),
      ),
    );
  }
}

And here is my code of button.dart

import 'main.dart';

class Button2 extends StatefulWidget {
  @override
  _Button2State createState() => _Button2State();
}

class _Button2State extends State<Button2> {
  String var2 = "text2";

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: <Widget>[
          RaisedButton(
            child: Text("button in second widget"),
            onPressed: () {
              setState(() {
                var2 = MyHomePageState().textController.text.toString();
              });
            },
          ),
          Text(var2),
        ],
      ),
    );
  }
}

Upvotes: 3

Views: 5677

Answers (2)

Navaneeth P
Navaneeth P

Reputation: 1561

Separate the function from the widget and pass the function.

In MyHomePageState:

// Extract the function
void onPressedFunction() {
  setState(() {
    var1 =  textController.text;
  });
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    // ...
    child: Column(
      children: <Widget>[
        RaisedButton(
          // ...
          onPressed: onPressedFunction, // function is extracted
        ),
        Text(var1),
        Button2(onPressedFunction), // pass the function
      ],
    ),
  ); 
}

In Button2:

class Button2 extends StatefulWidget {
  final Function onPressedFunction;

  Button2(this.onPressedFunction); // accept the function

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

class _Button2State extends State<Button2> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: <Widget>[
          RaisedButton(
            child: Text("button in second widget"),
            onPressed: widget.onPressedFunction, // use the same function
          ),
          Text(var2),
        ],
      ),
    );
  }
}

This way you Button2 will perform the same action as the first button on pressed.

Upvotes: 3

Mobina
Mobina

Reputation: 7109

You can use a GlobalKey of type MyHomePageState for MyHomePage and pass that to the button2's constructor. Using the GlobalKey you can call methods on the corresponding widget's state.

main.dart:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final GlobalKey<MyHomePageState> key = new GlobalKey(); // this is new
  final String title;

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

class MyHomePageState extends State<MyHomePage> {
  String var1 = "text1";
  TextEditingController textController = TextEditingController();
  
  @override
  void initState() {
    super.initState();
  }
  
  getText() { // this is new
    return textController.text; 
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("My app"),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            TextField(
              controller: textController,
            ),
            RaisedButton(
              child: Text("button in the same widget"),
              onPressed: () {
                setState(() {
                  var1 = textController.text;
                });
              },
            ),
            Text(var1),
            Button2(widget.key), // this has changed
          ],
        ),
      ),
    );
  }
}

button2.dart:

import 'package:flutter/material.dart';
import 'main.dart';
class Button2 extends StatefulWidget {
  final GlobalKey<MyHomePageState> homeKey; // this is new
  Button2(this.homeKey); // this is new
  @override
  _Button2State createState() => _Button2State();
}

class _Button2State extends State<Button2> {
  String var2 = "text2";

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: <Widget>[
          RaisedButton(
            child: Text("button in second widget"),
            onPressed: () {
              setState(() {
                var2 = widget.homeKey.currentState.getText(); // this is new
              });
            },
          ),
          Text(var2),
        ],
      ),
    );
  }
}

Upvotes: 1

Related Questions