【问题标题】:Flutter - How to access TextEditingController in other widget?Flutter - 如何在其他小部件中访问 TextEditingController?
【发布时间】:2020-11-20 16:22:14
【问题描述】:

我的 main.dart 中有一个 TextField,控制器名为 textcontroller。 在其他小部件(button.dart)中,我有一个按钮。如果我按下该按钮,它应该将 main.dart 中的 Text 小部件的文本设置为 TextField 的文本。只需执行与 main.dart 中的第一个按钮相同的操作即可。如何从其他小部件(文件)访问此 TextEditingController?

这是我的应用程序的视频,以便更好地理解。 https://streamable.com/xi0dn1

这是我的 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(),
          ],
        ),
      ),
    );
  }
}

这是我的 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),
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: android flutter dart


    【解决方案1】:

    将函数与小部件分离并传递函数。

    在我的主页状态中:

    // 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
          ],
        ),
      ); 
    }
    

    在 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),
            ],
          ),
        );
      }
    }
    

    这样,您的 Button2 将执行与按下第一个按钮相同的操作。

    【讨论】:

    • 感谢您的回答,但我需要访问控制器,而不是与第一个按钮相同。如果我在 Button2 中输入我的onPressed():setState(() { var2 = MyHomePageState().textController.text; });,它显示我在 textController 中的文本是“”(什么都没有)但有一个文本......我只需要知道是否需要向我的 textController 添加侦听器或其他东西显示文本....
    • 你正在创建一个新的MyHomePageState 对象。要么制作文本编辑控制器static 并使用MyHomePageState.textController.text,要么将控制器本身传递给Button2。第二种方法更可取imo。 @MatějMichálek
    【解决方案2】:

    您可以将MyHomePageState 类型的GlobalKey 用于MyHomePage,并将其传递给button2 的构造函数。使用GlobalKey,您可以调用相应小部件状态的方法。

    ma​​in.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),
            ],
          ),
        );
      }
    }
    

    【讨论】:

    • 感谢您的回答,但如果我在 Button2 onPressed 中设置为 setState(() {var2 = MyHomePageState().textController.text;});它只是表明 textController 的文本什么都不是。我应该添加一些侦听器还是更新 textController 以显示文本?
    • MyHomePageState().textController.text :这样,您正在创建 MyHomePageState 类的新实例,这不是您想要的。这就是为什么我建议你改用GlobalKey。通过使用GlobalKey,您将可以访问您已经拥有的MyHomePageState 实例(不是新实例)。 @MatějMichálek
    • 通过使用GlobalKey,您还可以访问textControllerMyHomePageState 中的所有其他方法/变量。 @MatějMichálek
    猜你喜欢
    • 1970-01-01
    • 2021-06-30
    • 2023-02-21
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 2019-12-23
    • 2019-03-16
    相关资源
    最近更新 更多