You need to enable JavaScript to run this app. Flutter 多Tab切换时TextField输入丢失,如何保留输入值
优惠活动
大模型
产品
解决方案
定价
更多

Flutter 多Tab切换时TextField输入丢失,如何保留输入值

问题描述

切换Tab时,此前已经在TextField内输入的内容会被清空丢失。
存在的核心疑问:

  • 切换Tab时要如何操作,才能保留页面上已输入的表单数据?
  • 输入内容消失的根本原因是什么?是否必须为TextField添加专属Controller才能解决该问题?
复现流程
  1. 在标签为“one”的Tab页的输入框内填写内容
  2. 切换到标签为“two”的Tab页,在对应输入框填写内容
  3. 切回“one”Tab时,该页TextField的已输入数据已经完全丢失
    该输入丢失问题在底部导航Tab的切换场景下也会稳定复现。
复现代码
import "package:flutter/material.dart";

class MultiTabScreen extends StatefulWidget {
  @override
  _MultiTabScreen createState() => _MultiTabScreen();
}

class _MultiTabScreen extends State<MultiTabScreen>
    with SingleTickerProviderStateMixin {
  TabController tabController;

  String title = "Home";

  @override
  void initState() {
    super.initState();
    tabController = new TabController(length: 3, vsync: this);
  }

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

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        theme: ThemeData(
            primarySwatch: Colors.purple,
            brightness: Brightness.light,
            accentColor: Colors.red),
        darkTheme: ThemeData(
          brightness: Brightness.dark,
        ),
        home: new Scaffold(
          appBar: AppBar(
            title: Text(title),
            centerTitle: true,
          ),
          body: TabBarView(
            children: <Widget>[
              FirstTab(),
              MyBody("Page Two"),
              MyBody("Page Three")
            ],
// 若需禁用Tab页滑动切换,可使用下方注释的代码
//            physics: NeverScrollableScrollPhysics(),
            controller: tabController,
          ),
          bottomNavigationBar: Material(
            color: Colors.purple,
            child: TabBar(
              onTap: (indedx) {
                if (indedx == 0) {
                  setState(() {
                    title = "Home";
                  });
                } else if (indedx == 1) {
                  setState(() {
                    title = "Tab Two";
                  });
                } else if (indedx == 2) {
                  setState(() {
                    title = "Tab Three";
                  });
                }
              },
              indicatorColor: Colors.blue,
              unselectedLabelColor: Colors.grey,
              tabs: <Widget>[
                Tab(
                  icon: Icon(Icons.favorite_border),
                  text: "ONE",
                ),
                Tab(
                  icon: Icon(Icons.favorite),
                  text: "TWO",
                ),
                Tab(
                  icon: Icon(Icons.add_box),
                  text: "THREE",
                ),
              ],
              controller: tabController,
            ),
          ),
        ));
  }
}

class FirstTab extends StatefulWidget {
  @override
  FirstTabState createState() => FirstTabState();
}

class FirstTabState extends State<FirstTab>
    with SingleTickerProviderStateMixin {
  TabController tabController;

  @override
  void initState() {
    super.initState();
    tabController = new TabController(length: 3, vsync: this);
  }

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

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: PreferredSize(
          preferredSize: Size.fromHeight(kToolbarHeight),
          child: Container(
            height: 50.0,
            child: new TabBar(
              indicatorColor: Colors.blue,
              unselectedLabelColor: Colors.grey,
              labelColor: Colors.blue,
              tabs: [
                Tab(
                  text: "ONE",
                ),
                Tab(
                  text: "TWO",
                ),
                Tab(
                  text: "THREE",
                ),
              ],
            ),
          ),
        ),
        body: TabBarView(
          children: [
            Container(              
              width: 300.0,
                child: TextField(
                  decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Number',
                ),
              ),
            ),
            Container(              
              width: 300.0,
                child: TextField(
                  decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Number',
                ),
              ),
            ),
            Container(              
              width: 300.0,
              child: TextField(
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'Number',
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class MyBody extends StatelessWidget {
  final String title;

  MyBody(this.title);

  final mySnackBar = SnackBar(
    content: Text(
      "Hello There!",
      style: TextStyle(color: Colors.white),
    ),
    duration: Duration(seconds: 3),
    backgroundColor: Colors.blue,
  );

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
        Container(              
          width: 300.0,
          child: TextField(
          decoration: InputDecoration(
          border: OutlineInputBorder(),
                labelText: 'Number',
              ),
            ),
          ),
        ],
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者龍が如く

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.13 19:24:05