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

Flutter类间传值问题:传递值时另一值被重置

解决AddAd类中Region和Category传值互相重置的问题

我明白你的问题了——每次从Regions选择区域后,AddAd里的分类就变回初始值,反过来选分类后区域也重置。这是因为你在跳转时没有把当前已选择的另一个值传递过去,导致每次都是用新页面里的初始空值来构建AddAd。

问题根源

比如在Regions类里,你定义的sCategory是类内部的局部变量,初始值是空的,所以当你选择区域后跳转到AddAd时,传递的sCategory是这个空值,而不是AddAd里之前已经选好的分类。同理,Categories类里的sRegion也是空的,跳转时会覆盖掉AddAd里已有的区域值。

解决方案

核心思路是:在跳转到Regions/Categories页面时,把AddAd当前已有的Region和Category值传过去,这样在选择完新值后,就能带着两个完整的值回到AddAd,不会丢失之前的选择。

步骤1:修改Regions类的构造函数,接收外部传入的现有值

class Regions extends StatefulWidget {
  // 接收来自AddAd的当前已选值
  final String existingRegion;
  final String existingCategory;

  Regions(this.existingRegion, this.existingCategory, {Key key}) : super(key: key);

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

class _RegionsState extends State<Regions> {
  String sRegion;
  String sCategory;

  @override
  void initState() {
    super.initState();
    // 初始化时使用传入的现有值
    sRegion = widget.existingRegion;
    sCategory = widget.existingCategory;
  }

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.rtl,
      child: Scaffold(
        appBar: AppBar(
          title: Text("Location"),
          actions: <Widget>[
            FlatButton(
              child: Text('Cancel', style: TextStyle(color: Colors.white),),
              onPressed: (){
                // 取消时也带回现有值
                Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>AddAd(sRegion, sCategory)));
              },
            )
          ],
        ),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.only(top:15.0),
            child: Container(
              child: Column(
                children: <Widget>[
                  for(var item in regions)
                    FlatButton(
                      child: Text(item),
                      onPressed: (){
                        sRegion = item;
                        // 跳转时同时传递已有的category值
                        Navigator.push(context, new MaterialPageRoute(builder: (context) => AddAd(sRegion, sCategory)));
                        print(sRegion);
                      },
                    ),
                  Divider(),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

步骤2:修改AddAd类中跳转到Regions/Categories的逻辑

在AddAd的State类里用局部变量保存当前选择的值,同时给ListTile添加跳转事件,传递当前完整的状态:

class _AddAdState extends State<AddAd> {
  // 用局部变量保存当前选择的值,方便修改和传递
  String currentRegion;
  String currentCategory;

  @override
  void initState() {
    super.initState();
    // 初始化时使用widget传入的值
    currentRegion = widget.sRegion;
    currentCategory = widget.sCategory;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // ... 其他原有代码
      body: Column(
        children: [
          ListTile(
            title: Text("Location"),
            subtitle: currentRegion == null ? Text("Where exactly") : Text(currentRegion),
            // 点击跳转到Regions,传递当前已选的两个值
            onTap: () {
              Navigator.push(context, MaterialPageRoute(
                builder: (context) => Regions(currentRegion, currentCategory)
              ));
            },
          ),
          ListTile(
            title: Text("Category"),
            subtitle: currentCategory == null ? Text("Department") : Text(currentCategory),
            // 点击跳转到Categories,传递当前已选的两个值
            onTap: () {
              Navigator.push(context, MaterialPageRoute(
                builder: (context) => Categories(currentRegion, currentCategory)
              ));
            },
          ),
          // ... 其他组件
        ],
      ),
    );
  }
}

步骤3:Categories类做和Regions类一致的修改

Categories类的结构和Regions完全对应,只需要把变量名换成分类相关的:

class Categories extends StatefulWidget {
  final String existingRegion;
  final String existingCategory;

  Categories(this.existingRegion, this.existingCategory, {Key key}) : super(key: key);

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

class _CategoriesState extends State<Categories> {
  String sRegion;
  String sCategory;

  @override
  void initState() {
    super.initState();
    sRegion = widget.existingRegion;
    sCategory = widget.existingCategory;
  }

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.rtl,
      child: Scaffold(
        appBar: AppBar(
          title: Text("Category"),
          actions: <Widget>[
            FlatButton(
              child: Text('Cancel', style: TextStyle(color: Colors.white),),
              onPressed: (){
                Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>AddAd(sRegion, sCategory)));
              },
            )
          ],
        ),
        body: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.only(top:15.0),
            child: Container(
              child: Column(
                children: <Widget>[
                  for(var item in categories) // 替换成你的分类列表
                    FlatButton(
                      child: Text(item),
                      onPressed: (){
                        sCategory = item;
                        // 跳转时传递已有的region值
                        Navigator.push(context, new MaterialPageRoute(builder: (context) => AddAd(sRegion, sCategory)));
                        print(sCategory);
                      },
                    ),
                  Divider(),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

为什么这样能解决问题?

现在每次跳转到Regions或Categories时,都会把AddAd当前已选的两个值传递过去,选择新值后,再把新值+原有值一起传回AddAd,这样两个值就不会互相覆盖重置了。另外用State类的局部变量保存状态,比直接使用widget的不可变属性更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:52:55