Flutter页面间值传递及基于滑块值修改容器与应用次要颜色
问题1:如何在Flutter的不同页面之间传递数值,并能在代码的各个部分使用该数值?
下面提供两种实用方案,覆盖临时全局传递和持久化存储场景:
方案1:用状态管理实现全局共享(Provider)
适合需要实时同步数值到多个页面的场景:
- 先在
pubspec.yaml添加依赖:
dependencies: flutter: sdk: flutter provider: ^6.0.5
- 创建全局状态类:
import 'package:flutter/foundation.dart'; class AppState extends ChangeNotifier { double _sliderValue = 125; double get sliderValue => _sliderValue; set sliderValue(double newValue) { _sliderValue = newValue; notifyListeners(); // 通知所有监听组件更新 } }
- 在
main.dart中包裹根组件:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'app_state.dart'; import 'settings_page.dart'; import 'home_page.dart'; void main() { runApp( ChangeNotifierProvider( create: (context) => AppState(), child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( initialRoute: '/', routes: { '/': (context) => const HomePage(), '/settings': (context) => const SettingsPage(), }, ); } }
- 设置页中读写滑块值:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'app_state.dart'; class SettingsPage extends StatelessWidget { const SettingsPage({super.key}); @override Widget build(BuildContext context) { final appState = Provider.of<AppState>(context); return Scaffold( appBar: AppBar(title: const Text('设置')), body: Slider( value: appState.sliderValue, label: appState.sliderValue.toString(), divisions: 23, min: 0, max: 250, onChanged: (newValue) => appState.sliderValue = newValue, ), ); } }
- 主页中获取全局数值:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'app_state.dart'; class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { final appState = Provider.of<AppState>(context); return Scaffold( appBar: AppBar(title: const Text('主页')), body: Center( child: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height * 0.858, decoration: BoxDecoration(color: Color(0xFFEEEEEE)), ), ), floatingActionButton: FloatingActionButton( onPressed: () => Navigator.pushNamed(context, '/settings'), child: const Icon(Icons.settings), ), ); } }
方案2:用SharedPreferences实现持久化存储
需要重启APP后保留数值的场景用这个:
- 添加依赖:
dependencies: shared_preferences: ^2.2.2
- 设置页中保存数值:
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class SettingsPage extends StatefulWidget { const SettingsPage({super.key}); @override State<SettingsPage> createState() => _SettingsPageState(); } class _SettingsPageState extends State<SettingsPage> { double _sliderValue = 125; @override void initState() { super.initState(); _loadSavedValue(); } Future<void> _loadSavedValue() async { final prefs = await SharedPreferences.getInstance(); setState(() => _sliderValue = prefs.getDouble('sliderValue') ?? 125); } Future<void> _saveValue(double value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setDouble('sliderValue', value); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('设置')), body: Slider( value: _sliderValue, label: _sliderValue.toString(), divisions: 23, min: 0, max: 250, onChanged: (newValue) { setState(() => _sliderValue = newValue); _saveValue(newValue); }, ), ); } }
- 主页中读取数值:
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { double _sliderValue = 125; @override void initState() { super.initState(); _loadSavedValue(); } Future<void> _loadSavedValue() async { final prefs = await SharedPreferences.getInstance(); setState(() => _sliderValue = prefs.getDouble('sliderValue') ?? 125); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('主页')), body: Center( child: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height * 0.858, decoration: BoxDecoration(color: Color(0xFFEEEEEE)), ), ), floatingActionButton: FloatingActionButton( onPressed: () async { await Navigator.pushNamed(context, '/settings'); _loadSavedValue(); // 返回后刷新数值 }, child: const Icon(Icons.settings), ), ); } }
问题2:如何基于滑块的取值来更改上述容器的颜色以及应用的次要颜色?
结合状态管理的方案最简洁,直接在全局状态类中添加颜色计算逻辑:
步骤1:扩展AppState类,添加颜色计算方法
import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; class AppState extends ChangeNotifier { double _sliderValue = 125; double get sliderValue => _sliderValue; set sliderValue(double newValue) { _sliderValue = newValue; notifyListeners(); } // 根据滑块值计算容器颜色(示例:从红到蓝渐变) Color get containerColor { double ratio = _sliderValue / 250; int red = (255 * (1 - ratio)).toInt(); int blue = (255 * ratio).toInt(); return Color.fromRGBO(red, 100, blue, 1); } // 根据滑块值返回次要颜色(分段切换) Color get secondaryColor { if (_sliderValue < 80) return Colors.orange; if (_sliderValue < 160) return Colors.purple; return Colors.teal; } }
步骤2:在页面中使用动态颜色
// 主页中的Container和AppBar示例 class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { final appState = Provider.of<AppState>(context); return Scaffold( appBar: AppBar( title: const Text('主页'), backgroundColor: appState.secondaryColor, // 应用次要颜色 ), body: Center( child: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height * 0.858, decoration: BoxDecoration( color: appState.containerColor, // 动态容器颜色 ), ), ), floatingActionButton: FloatingActionButton( onPressed: () => Navigator.pushNamed(context, '/settings'), child: const Icon(Icons.settings), ), ); } }
如果不需要全局同步,也可以直接在接收滑块值的页面中写颜色计算函数,根据传入的数值实时生成颜色。
内容的提问来源于stack exchange,提问作者bird
相关产品推荐
相关产品推荐

