You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter跨页面传递TextEditingController值及编辑异常问题

解决Flutter页面间文本内容传递与编辑问题

问题描述

我想把InformationContentDetails页面中通过TextEditingController创建的文本值传递到NeuigkeitenContentDetails页面并显示,但NeuigkeitenContentDetails页面无法识别原页面的TextEditingController,完全无法进行编辑操作。

原代码

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

      @override

      State<InformationContentDetails> createState() => _InformationContentDetails();
    }
    class _InformationContentDetails extends State<InformationContentDetails> {
      bool isEnable = false;
      var _controller = new TextEditingController(text: 'Allgemeine Informationen');
      var _controller2 = TextEditingController();

      String  name = "Allgemeine Informationen";
      String name2 = "Herzlich Willkommen ...";

      textlistener(){
        print("Update: ${_controller.text}");
        print("Update: ${_controller2.text}");

      }
      @override
      void initState() {
        super.initState();
        // Start listening to changes
        _controller.addListener(textlistener);
        _controller2.addListener(textlistener);
      }



      @override
      Widget build(BuildContext context) {
        return ResponsiveBuilder(
          builder: (context, sizingInformation) {
            var textAlignment;
            if (sizingInformation.deviceScreenType == DeviceScreenType.desktop) {
              textAlignment = TextAlign.left;
            } else {
              textAlignment = TextAlign.center;
            }

            return Container(
              width: 650,
              child: SingleChildScrollView(
                child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    "${_controller.text}",
                    style: titleTextStyle(sizingInformation.deviceScreenType),
                    textAlign: textAlignment,
                  ),
                  TextField(
                    enabled: true,
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                    hintText: "Informationen aktualisieren",
                    ),
                    controller : _controller,
                  ),
                  FlatButton(
                    child: Text('bearbeiten'),
                    onPressed:(){
                      setState((){
                        name = _controller.text;
                        isEnable = !isEnable;

                      });
                    },

                  ),
                  Text(
                    name2,
                    style: descriptionTextStyle(sizingInformation.deviceScreenType),
                    textAlign: textAlignment,
                  ),
                  Container(
                    child: TextField(
                      decoration: InputDecoration(
                        border: OutlineInputBorder(),
                        hintText: "Informationstext aktualisieren"
                      ),
                      controller : _controller2,

                    ),
                  ),
                  Container(
                    child: FlatButton(
                      child: Text('bearbeiten'),
                      onPressed:(){
                        setState((){
                          name2 = _controller2.text;
                          isEnable = !isEnable;

                        });
                      },

                    ),
                  ),


                ],
              )),
            );
          },
        );
      }
      @override
      void dispose() {
        _controller.dispose();
        _controller2.dispose();
        super.dispose();


      }
    }

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

  @override
  State<NeuigkeitenContentDetails> createState() => _NeuigkeitenContentDetailsState();
}

class _NeuigkeitenContentDetailsState extends State<NeuigkeitenContentDetails> {
  @override
  Widget build(BuildContext context) {
    return ResponsiveBuilder(
      builder: (context, sizingInformation) {
        var textAlignment;
        if (sizingInformation.deviceScreenType == DeviceScreenType.desktop) {
          textAlignment = TextAlign.left;
        } else {
          textAlignment = TextAlign.center;
        }

        return Container(
          width: 650,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[

              Text(
                'Neuigkeiten',
                style: titleTextStyle(sizingInformation.deviceScreenType),
                textAlign: textAlignment,
              ),
              SizedBox(
                height: 30,
              ),
              Text(
                'Herzlich Willkommen',
                style: descriptionTextStyle(sizingInformation.deviceScreenType),
                textAlign: textAlignment,
              )
            ],
          ),
        );
      },
    );
  }
}

解决方案

核心原则

不要跨页面直接共享TextEditingController,每个页面应维护自己的控制器,避免生命周期冲突(比如原页面销毁后控制器被释放,导致目标页面报错)。我们需要传递的是文本内容,而非控制器本身。


方案1:构造函数传值(简单场景适用)

1. 修改NeuigkeitenContentDetails组件

让它接收外部传入的文本,内部创建自己的控制器:

class NeuigkeitenContentDetails extends StatefulWidget {
  // 接收传递的标题和内容文本
  final String titleText;
  final String contentText;

  const NeuigkeitenContentDetails({
    Key key,
    required this.titleText,
    required this.contentText,
  }) : super(key: key);

  @override
  State<NeuigkeitenContentDetails> createState() => _NeuigkeitenContentDetailsState();
}

class _NeuigkeitenContentDetailsState extends State<NeuigkeitenContentDetails> {
  late TextEditingController _titleController;
  late TextEditingController _contentController;

  @override
  void initState() {
    super.initState();
    // 用传入的文本初始化本地控制器
    _titleController = TextEditingController(text: widget.titleText);
    _contentController = TextEditingController(text: widget.contentText);
  }

  @override
  void dispose() {
    // 销毁本地控制器
    _titleController.dispose();
    _contentController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ResponsiveBuilder(
      builder: (context, sizingInformation) {
        var textAlignment = sizingInformation.deviceScreenType == DeviceScreenType.desktop
            ? TextAlign.left
            : TextAlign.center;

        return Container(
          width: 650,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              TextField(
                controller: _titleController,
                style: titleTextStyle(sizingInformation.deviceScreenType),
                textAlign: textAlignment,
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: "Neuigkeiten Titel",
                ),
              ),
              SizedBox(height: 30),
              TextField(
                controller: _contentController,
                style: descriptionTextStyle(sizingInformation.deviceScreenType),
                textAlign: textAlignment,
                maxLines: null,
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: "Neuigkeiten Inhalt",
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}
2. 从InformationContentDetails传递值

在跳转或调用NeuigkeitenContentDetails时,传入当前控制器的文本:

// 示例:在InformationContentDetails的按钮点击事件中跳转
FlatButton(
  child: Text('跳转到Neuigkeiten'),
  onPressed: () {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => NeuigkeitenContentDetails(
          titleText: _controller.text,
          contentText: _controller2.text,
        ),
      ),
    );
  },
)

方案2:状态管理工具(复杂场景适用)

如果需要两个页面实时同步文本内容,或有更多组件共享状态,建议用Provider、Riverpod等状态管理库。以Riverpod为例:

1. 定义全局状态
final titleTextProvider = StateProvider<String>((ref) => 'Allgemeine Informationen');
final contentTextProvider = StateProvider<String>((ref) => 'Herzlich Willkommen ...');
2. 在InformationContentDetails中绑定状态
class _InformationContentDetailsState extends State<InformationContentDetails> {
  late TextEditingController _controller;
  late TextEditingController _controller2;
  final ref = ref.watch; // 需引入riverpod依赖

  @override
  void initState() {
    super.initState();
    // 从状态中读取初始值
    final initialTitle = ref(titleTextProvider.notifier).state;
    final initialContent = ref(contentTextProvider.notifier).state;
    
    _controller = TextEditingController(text: initialTitle);
    _controller2 = TextEditingController(text: initialContent);
    
    // 监听文本变化,同步到全局状态
    _controller.addListener(() {
      ref(titleTextProvider.notifier).state = _controller.text;
    });
    _controller2.addListener(() {
      ref(contentTextProvider.notifier).state = _controller2.text;
    });
  }

  // 其余代码保持不变...
}
3. 在NeuigkeitenContentDetails中读取并编辑状态
class _NeuigkeitenContentDetailsState extends State<NeuigkeitenContentDetails> {
  late TextEditingController _titleController;
  late TextEditingController _contentController;
  final ref = ref.watch;

  @override
  void initState() {
    super.initState();
    // 从全局状态读取初始值
    final initialTitle = ref(titleTextProvider.notifier).state;
    final initialContent = ref(contentTextProvider.notifier).state;
    
    _titleController = TextEditingController(text: initialTitle);
    _contentController = TextEditingController(text: initialContent);
    
    // 同步本地编辑到全局状态
    _titleController.addListener(() {
      ref(titleTextProvider.notifier).state = _titleController.text;
    });
    _contentController.addListener(() {
      ref(contentTextProvider.notifier).state = _contentController.text;
    });
  }

  // 其余代码保持不变...
}

内容的提问来源于stack exchange,提问作者astas33

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 08:45:39