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

Flutter页面间数据传递问题:如何同步设置页与首页数据

Flutter页面间数据传递:设置页单位同步到首页

我知道这类问题有很多相关提问,但我是Flutter新手,还没找到契合自身需求的方案,可能我的思路有偏差。在Flutter开发中,几乎每个页面都需要向其他页面传递数据,也可能需要从其他页面接收返回的数据。

以下是我的相关代码:

home.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'applicationbar.dart';
import 'navigationdrawer.dart';
import 'bluetooth.dart';


class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String _string = '0m';  //若settings.dart中_isFeetChecked为true,则此处显示'0ft'


  @override
  Widget build(BuildContext context) {

    return Scaffold(
      backgroundColor: Colors.grey[900],
      appBar: ApplicationBar(title: 'Luggage Follower'),
      drawer: NavigationDrawer(),
      body:Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
            child: Text('good Status', style: Theme.of(context).textTheme.body2),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
            child: Text('Paired', style: Theme.of(context).textTheme.body1),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 20,horizontal: 0),
            child: Divider(height: 3.0, color: Colors.pinkAccent, indent: 150, endIndent: 150),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
            child: Text('Distance to Luggage', style: Theme.of(context).textTheme.body2),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
            child: Text(_string, style: Theme.of(context).textTheme.body1), //动态文本
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 10,horizontal: 0),
            child: LuggageFollow(),
          ),
        ],
      ),
    );
  }
}

settings.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/audio_cache.dart';

import 'applicationbar.dart';
import 'navigationdrawer.dart';

class SettingsData {
  bool feet;
  bool metres;

  SettingsData({this.feet, this.metres});
}

class Settings extends StatefulWidget {
  @override
  _SettingsState createState() => _SettingsState();
}

class _SettingsState extends State<Settings> {
  static bool _isFeetChecked   = false;
  static bool _isMetersChecked = true;


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: ApplicationBar(title: 'Settings'),
      drawer: NavigationDrawer(),
      body: Column(
          //crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 20),
              child: Text('Distance Units')
            ),
            Divider(
              height: 3.0,
              color: Colors.pink,
            ),
            Padding(
              padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 0),
              child: CheckboxListTile(
                title: Text('Distance in feet', style: Theme.of(context).textTheme.body1),
                value: _isFeetChecked,
                onChanged: (bool value) {
                  setState(() {
                    _isFeetChecked = value; _isMetersChecked = !value;});
                },
                checkColor: Colors.white,
                activeColor: Colors.pink,
                subtitle: Text('1 foot ~ 0.3 metres',style: Theme.of(context).textTheme.display2),
              ),
            ),
            Padding(
              padding: EdgeInsets.symmetric(vertical: 20.0,horizontal: 0),
              child: CheckboxListTile(
                title: Text('Distance in metres', style: Theme.of(context).textTheme.body1),
                value: _isMetersChecked,
                onChanged: (bool value) {
                  setState(() { _isMetersChecked = value; _isFeetChecked = !value;updateData();});
                },
                checkColor: Colors.white,
                activeColor: Colors.pink,
                subtitle: Text('1 metre ~ 3 feet',style: Theme.of(context).textTheme.display2),
              ),
            ),
            Padding(
              padding: EdgeInsets.symmetric(vertical: 30.0,horizontal: 20),
              child: Text('Notifications')
            ),
            Divider(
                height: 3.0,
                color: Colors.pink,
            ),

              ),
            ),
          ],
      ),
    );
  }
}

我需要实现设置页的单位选择同步到首页的显示,请问该如何实现Flutter页面间的数据传递?


解决方案

针对你的需求,这里提供三种适合新手的实现方式,从简单到进阶:

方法一:使用Navigator返回数据(临时传递,不持久化)

这种方法适合从设置页返回首页时同步数据,不需要依赖第三方库。

修改步骤:

  1. 修改Settings页面,添加返回数据逻辑
    去掉静态变量(静态变量不适合组件间状态管理),在用户选择单位后通过Navigator.pop返回数据:

    class _SettingsState extends State<Settings> {
      bool _isFeetChecked = false;
      bool _isMetersChecked = true;
    
      // 返回数据给首页
      void _navigateBack() {
        Navigator.pop(context, SettingsData(feet: _isFeetChecked, metres: _isMetersChecked));
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: ApplicationBar(
            title: 'Settings',
            leading: IconButton(
              icon: Icon(Icons.arrow_back),
              onPressed: _navigateBack,
            ),
          ),
          body: Column(
            children: [
              // ... 其他代码
              CheckboxListTile(
                title: Text('Distance in feet', style: Theme.of(context).textTheme.body1),
                value: _isFeetChecked,
                onChanged: (bool? value) {
                  setState(() {
                    _isFeetChecked = value ?? false; 
                    _isMetersChecked = !_isFeetChecked;
                  });
                  _navigateBack(); // 选择后立即返回同步
                },
                // ... 其他属性不变
              ),
              // 另一个Checkbox同理修改onChanged
            ],
          ),
        );
      }
    }
    
  2. 修改Home页面,接收返回数据
    打开Settings页面时用await Navigator.push接收返回值,更新显示:

    class _HomeState extends State<Home> {
      String _string = '0m';
    
      // 打开设置页面的方法(从Drawer或AppBar触发)
      void _openSettings() async {
        final result = await Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => Settings()),
        );
    
        if (result != null && result is SettingsData) {
          setState(() {
            _string = result.feet ? '0ft' : '0m';
          });
        }
      }
    
      // 对应修改NavigationDrawer的跳转逻辑,调用_openSettings即可
    }
    

方法二:使用单例类管理全局状态(适合小型应用)

如果需要多个页面共享状态,且不需要持久化,用单例类存储设置数据。

步骤:

  1. 创建全局设置单例类

    class AppSettings {
      static final AppSettings _instance = AppSettings._internal();
      bool isFeetChecked = false;
      bool isMetersChecked = true;
    
      factory AppSettings() => _instance;
      AppSettings._internal();
    }
    
  2. 修改Settings页面,更新单例数据

    class _SettingsState extends State<Settings> {
      late AppSettings _settings;
    
      @override
      void initState() {
        super.initState();
        _settings = AppSettings();
        // 初始化当前状态为单例中的数据
        _isFeetChecked = _settings.isFeetChecked;
        _isMetersChecked = _settings.isMetersChecked;
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          // ... 其他代码
          CheckboxListTile(
            title: Text('Distance in feet'),
            value: _isFeetChecked,
            onChanged: (bool? value) {
              setState(() {
                _isFeetChecked = value ?? false;
                _isMetersChecked = !_isFeetChecked;
                // 更新单例中的全局数据
                _settings.isFeetChecked = _isFeetChecked;
                _settings.isMetersChecked = _isMetersChecked;
              });
            },
          ),
          // 另一个Checkbox同理修改
        );
      }
    }
    
  3. 修改Home页面,获取并显示单例数据

    class _HomeState extends State<Home> {
      String _string = '0m';
      late AppSettings _settings;
    
      @override
      void initState() {
        super.initState();
        _settings = AppSettings();
        _updateDisplay();
      }
    
      void _updateDisplay() {
        setState(() {
          _string = _settings.isFeetChecked ? '0ft' : '0m';
        });
      }
    
      // 打开设置页面返回后刷新显示
      void _openSettings() async {
        await Navigator.push(context, MaterialPageRoute(builder: (context) => Settings()));
        _updateDisplay();
      }
    }
    

方法三:使用SharedPreferences持久化设置(进阶,重启APP保留设置)

如果希望用户设置在APP重启后依然有效,用SharedPreferences存储。

步骤:

  1. 添加依赖
    在pubspec.yaml中添加:

    dependencies:
      shared_preferences: ^2.2.2
    
  2. 修改Settings页面,保存/加载设置

    import 'package:shared_preferences/shared_preferences.dart';
    
    class _SettingsState extends State<Settings> {
      bool _isFeetChecked = false;
      bool _isMetersChecked = true;
    
      @override
      void initState() {
        super.initState();
        _loadSavedSettings(); // 加载之前保存的设置
      }
    
      // 加载本地存储的设置
      Future<void> _loadSavedSettings() async {
        final prefs = await SharedPreferences.getInstance();
        setState(() {
          _isFeetChecked = prefs.getBool('isFeetChecked') ?? false;
          _isMetersChecked = !_isFeetChecked;
        });
      }
    
      // 保存设置到本地
      Future<void> _saveSettings() async {
        final prefs = await SharedPreferences.getInstance();
        await prefs.setBool('isFeetChecked', _isFeetChecked);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          // ... 其他代码
          CheckboxListTile(
            title: Text('Distance in feet'),
            value: _isFeetChecked,
            onChanged: (bool? value) {
              setState(() {
                _isFeetChecked = value ?? false;
                _isMetersChecked = !_isFeetChecked;
              });
              _saveSettings(); // 保存设置
            },
          ),
          // 另一个Checkbox同理修改
        );
      }
    }
    
  3. 修改Home页面,加载并显示持久化设置

    import 'package:shared_preferences/shared_preferences.dart';
    
    class _HomeState extends State<Home> {
      String _string = '0m';
    
      @override
      void initState() {
        super.initState();
        _loadSettings();
      }
    
      Future<void> _loadSettings() async {
        final prefs = await SharedPreferences.getInstance();
        final isFeet = prefs.getBool('isFeetChecked') ?? false;
        setState(() {
          _string = isFeet ? '0ft' : '0m';
        });
      }
    
      // 打开设置页面返回后重新加载
      void _openSettings() async {
        await Navigator.push(context, MaterialPageRoute(builder: (context) => Settings()));
        _loadSettings();
      }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 03:47:03