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

Flutter:如何用Riverpod结合file_picker替代setState实现文件夹选择

Riverpod 结合 file_picker 实现文件夹选择(替代 StatefulWidget)

1. 先完善你的 StateNotifier 和对应 Provider

首先把你提到的两个状态管理类和 Provider 补全,确保状态可以被监听和更新:

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:file_picker/file_picker.dart';

// 存储选中的文件夹路径
class FolderPathNotifier extends StateNotifier<String?> {
  FolderPathNotifier() : super(null);

  // 更新路径的方法
  void updatePath(String? newPath) {
    state = newPath;
  }
}

// 存储用户是否取消选择的状态
class IsCancelledNotifier extends StateNotifier<bool> {
  IsCancelledNotifier() : super(false);

  // 更新取消状态的方法
  void setCancelled(bool value) {
    state = value;
  }
}

// 注册对应的全局 Provider
final folderPathProvider = StateNotifierProvider<FolderPathNotifier, String?>((ref) {
  return FolderPathNotifier();
});

final isCancelledProvider = StateNotifierProvider<IsCancelledNotifier, bool>((ref) {
  return IsCancelledNotifier();
});

2. 用 ConsumerWidget 实现选择逻辑

直接在 ConsumerWidget 里实现文件夹选择方法,通过 ref 读取和更新 StateNotifier 的状态,替代原来的 setState:

class FolderPickerPage extends ConsumerWidget {
  const FolderPickerPage({super.key});

  Future<void> _selectFolder(WidgetRef ref) async {
    // 调用 file_picker 的文件夹选择 API
    final result = await FilePicker.platform.getDirectoryPath();

    if (result != null) {
      // 用户选中了文件夹:更新路径、重置取消状态
      ref.read(folderPathProvider.notifier).updatePath(result);
      ref.read(isCancelledProvider.notifier).setCancelled(false);
    } else {
      // 用户取消了选择:更新取消状态、清空路径
      ref.read(isCancelledProvider.notifier).setCancelled(true);
      ref.read(folderPathProvider.notifier).updatePath(null);
    }
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // 监听状态变化,自动触发 UI 重建
    final currentPath = ref.watch(folderPathProvider);
    final isCancelled = ref.watch(isCancelledProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('文件夹选择')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            if (currentPath != null)
              Text('选中路径:$currentPath')
            else if (isCancelled)
              const Text('你取消了选择')
            else
              const Text('未选择文件夹'),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => _selectFolder(ref),
              child: const Text('选择文件夹'),
            ),
          ],
        ),
      ),
    );
  }
}

核心逻辑说明

  • 用 ref.read(xxxProvider.notifier) 获取 StateNotifier 实例,调用其方法更新状态,替代 StatefulWidget 里的 setState。
  • 用 ref.watch(xxxProvider) 在 build 方法中监听状态变化,状态更新时会自动触发 UI 重建。
  • 不需要手动管理状态生命周期,Riverpod 会自动处理状态的创建和销毁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 21:25:01