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

Flutter无需导航将用户选择的日期传递至第二页的实现方案

可行解决方案

方案1:全局变量(快速实现,适合小型项目)

定义全局日期变量,选择日期后赋值,第二页直接引用。注意全局变量在APP生命周期内会保留,若需清理可在页面销毁时重置。

实现步骤:

  1. 创建全局变量文件(如globals.dart):
import 'dart:core';

DateTime? selectedDate;
  1. 日期选择页面赋值:
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;
  1. 修改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重启也能保留上次选择的日期。

实现步骤:

  1. 添加依赖到pubspec.yaml:
dependencies:
  shared_preferences: ^2.2.2
  1. 日期选择后保存:
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));
  1. 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定义或监听方式有误,以下是正确实现:

实现步骤:

  1. 添加Riverpod依赖:
dependencies:
  flutter_riverpod: ^2.3.0
  1. 定义StateProvider保存选中日期:
import 'package:flutter_riverpod/flutter_riverpod.dart';

final selectedDateProvider = StateProvider<DateTime?>((ref) => null);
  1. 日期选择页面更新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;
  1. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 13:40:43