Flutter无需导航将用户选择的日期传递至第二页的实现方案
可行解决方案
方案1:全局变量(快速实现,适合小型项目)
定义全局日期变量,选择日期后赋值,第二页直接引用。注意全局变量在APP生命周期内会保留,若需清理可在页面销毁时重置。
实现步骤:
- 创建全局变量文件(如
globals.dart):
import 'dart:core'; DateTime? selectedDate;
- 日期选择页面赋值:
final initialDate = DateTime.now(); final newDate = await showDatePicker( context: context, initialDate: initialDate, firstDate: DateTime(DateTime.now().year), lastDate: DateTime.now()); if (newDate == null) return; // 赋值给全局变量 selectedDate = newDate;
- 修改SugarPhotoPage代码,动态初始化Stream:
import 'globals.dart'; import 'package:intl/intl.dart'; class SugarPhotoPage extends StatefulWidget { const SugarPhotoPage({super.key}); @override State<SugarPhotoPage> createState() => _SugarPhotoPageState(); } class _SugarPhotoPageState extends State<SugarPhotoPage> { late Stream<QuerySnapshot> _photoStream; final DateFormat _dateFormat = DateFormat('yyyy-MM-dd'); @override void initState() { super.initState(); // 处理日期未选择的默认情况 final targetDate = selectedDate ?? DateTime.now(); _photoStream = FirebaseFirestore.instance .collection('photos') .doc(_dateFormat.format(targetDate)) .collection('Today Photos') .snapshots(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(backgroundColor: Colors.transparent, elevation: 0), body: StreamBuilder<QuerySnapshot>( stream: _photoStream, builder: (context, snapshot) { if (snapshot.hasError) { return const Text('Something went wrong'); } if (snapshot.connectionState == ConnectionState.waiting) { return const Text("Loading"); } if (snapshot.hasData) { return SafeArea( child: Center( child: ListView( children: snapshot.data!.docs .map((DocumentSnapshot documentSnapshot) { Map<String, dynamic> data = documentSnapshot.data()! as Map<String, dynamic>; return ListTile( leading: Container( height: 100, width: 100, decoration: BoxDecoration( image: DecorationImage( image: NetworkImage('${data['ImgUrl']}'), fit: BoxFit.cover, ), ), ), ); }).toList(), ), ), ); } return const Text('Loading'); }), ); } }
方案2:SharedPreferences持久化日期(适合需保存选择记录的场景)
将选择的日期存入本地存储,第二页读取后使用,即使APP重启也能保留上次选择的日期。
实现步骤:
- 添加依赖到
pubspec.yaml:
dependencies: shared_preferences: ^2.2.2
- 日期选择后保存:
import 'package:shared_preferences/shared_preferences.dart'; import 'package:intl/intl.dart'; final initialDate = DateTime.now(); final newDate = await showDatePicker( context: context, initialDate: initialDate, firstDate: DateTime(DateTime.now().year), lastDate: DateTime.now()); if (newDate == null) return; // 格式化并存入本地存储 final prefs = await SharedPreferences.getInstance(); await prefs.setString('selected_date', DateFormat('yyyy-MM-dd').format(newDate));
- SugarPhotoPage中读取并初始化Stream:
import 'package:shared_preferences/shared_preferences.dart'; import 'package:intl/intl.dart'; class SugarPhotoPage extends StatefulWidget { const SugarPhotoPage({super.key}); @override State<SugarPhotoPage> createState() => _SugarPhotoPageState(); } class _SugarPhotoPageState extends State<SugarPhotoPage> { late Stream<QuerySnapshot> _photoStream; final DateFormat _dateFormat = DateFormat('yyyy-MM-dd'); @override void initState() { super.initState(); _initStream(); } Future<void> _initStream() async { final prefs = await SharedPreferences.getInstance(); // 读取保存的日期,默认当前日期 final dateStr = prefs.getString('selected_date') ?? _dateFormat.format(DateTime.now()); setState(() { _photoStream = FirebaseFirestore.instance .collection('photos') .doc(dateStr) .collection('Today Photos') .snapshots(); }); } @override Widget build(BuildContext context) { // 后续build代码同方案1,此处省略重复部分 return Scaffold( appBar: AppBar(backgroundColor: Colors.transparent, elevation: 0), body: StreamBuilder<QuerySnapshot>( stream: _photoStream, builder: (context, snapshot) { // 原builder逻辑不变 }), ); } }
方案3:修正Riverpod用法(状态管理推荐方案)
若之前使用Riverpod失败,大概率是Provider定义或监听方式有误,以下是正确实现:
实现步骤:
- 添加Riverpod依赖:
dependencies: flutter_riverpod: ^2.3.0
- 定义StateProvider保存选中日期:
import 'package:flutter_riverpod/flutter_riverpod.dart'; final selectedDateProvider = StateProvider<DateTime?>((ref) => null);
- 日期选择页面更新Provider:
import 'package:flutter_riverpod/flutter_riverpod.dart'; final initialDate = DateTime.now(); final newDate = await showDatePicker( context: context, initialDate: initialDate, firstDate: DateTime(DateTime.now().year), lastDate: DateTime.now()); if (newDate == null) return; // 更新Provider状态 ref.read(selectedDateProvider.notifier).state = newDate;
- SugarPhotoPage中监听Provider并获取Stream:
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; class SugarPhotoPage extends ConsumerStatefulWidget { const SugarPhotoPage({super.key}); @override ConsumerState<SugarPhotoPage> createState() => _SugarPhotoPageState(); } class _SugarPhotoPageState extends ConsumerState<SugarPhotoPage> { late Stream<QuerySnapshot> _photoStream; final DateFormat _dateFormat = DateFormat('yyyy-MM-dd'); @override void initState() { super.initState(); _initStream(); } void _initStream() { // 监听Provider状态变化,动态更新Stream ref.listen(selectedDateProvider, (previous, next) { if (next != null) { setState(() { _photoStream = FirebaseFirestore.instance .collection('photos') .doc(_dateFormat.format(next)) .collection('Today Photos') .snapshots(); }); } }); // 初始化时获取当前状态 final selectedDate = ref.read(selectedDateProvider); if (selectedDate != null) { _photoStream = FirebaseFirestore.instance .collection('photos') .doc(_dateFormat.format(selectedDate)) .collection('Today Photos') .snapshots(); } else { // 默认使用当前日期 _photoStream = FirebaseFirestore.instance .collection('photos') .doc(_dateFormat.format(DateTime.now())) .collection('Today Photos') .snapshots(); } } @override Widget build(BuildContext context) { // 后续build代码同方案1,此处省略重复部分 return Scaffold( appBar: AppBar(backgroundColor: Colors.transparent, elevation: 0), body: StreamBuilder<QuerySnapshot>( stream: _photoStream, builder: (context, snapshot) { // 原builder逻辑不变 }), ); } }
注意:使用Riverpod时,需将根组件用ProviderScope包裹。
内容的提问来源于stack exchange,提问作者DAni M
相关产品推荐
相关产品推荐

