Flutter中Stacked架构实现及stacked_services服务使用咨询
Flutter Stacked架构实现与stacked_services核心功能指南
以下是实现Stacked架构并使用stacked_services完成导航、弹窗功能的完整步骤:
一、依赖配置
首先在pubspec.yaml中添加所需依赖:
dependencies: flutter: sdk: flutter stacked: ^3.4.0 stacked_services: ^1.1.0 get_it: ^7.2.0
执行flutter pub get安装依赖。
二、初始化依赖注入容器
创建locator.dart文件,注册stacked_services提供的核心服务:
import 'package:get_it/get_it.dart'; import 'package:stacked_services/stacked_services.dart'; final locator = GetIt.instance; void setupLocator() { // 注册导航服务 locator.registerLazySingleton(() => NavigationService()); // 注册弹窗服务 locator.registerLazySingleton(() => DialogService()); }
在main.dart的入口函数中初始化容器:
void main() { setupLocator(); runApp(const MyApp()); }
三、Stacked Routing页面导航实现
1. 定义路由表
创建router.dart,配置页面路由映射:
import 'package:flutter/material.dart'; import '../views/home_view.dart'; import '../views/detail_view.dart'; // 路由名称常量 const String homeRoute = '/'; const String detailRoute = '/detail'; // 路由映射表 final Map<String, Widget Function(BuildContext)> routes = { homeRoute: (context) => const HomeView(), detailRoute: (context) => const DetailView(), };
2. ViewModel中调用导航
以HomeViewModel为例,通过locator获取导航服务实现跳转:
import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; import '../locator.dart'; class HomeViewModel extends BaseViewModel { final _navigationService = locator<NavigationService>(); // 跳转到详情页并传递参数 void navigateToDetail() { _navigationService.navigateTo(detailRoute, arguments: '首页传递的内容'); } }
3. 页面接收导航参数
在DetailViewModel中获取传递的参数:
import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; import '../locator.dart'; class DetailViewModel extends BaseViewModel { final _navigationService = locator<NavigationService>(); String? receivedData; void init() { // 获取导航参数 receivedData = _navigationService.currentArguments as String?; notifyListeners(); } }
4. 页面Widget绑定ViewModel
HomeView的实现:
import 'package:flutter/material.dart'; import 'package:stacked/stacked.dart'; import '../viewmodels/home_viewmodel.dart'; class HomeView extends StatelessWidget { const HomeView({super.key}); @override Widget build(BuildContext context) { return ViewModelBuilder<HomeViewModel>.reactive( viewModelBuilder: () => HomeViewModel(), builder: (context, viewModel, child) => Scaffold( appBar: AppBar(title: const Text('首页')), body: Center( child: ElevatedButton( onPressed: viewModel.navigateToDetail, child: const Text('跳转详情页'), ), ), ), ); } }
DetailView的实现:
import 'package:flutter/material.dart'; import 'package:stacked/stacked.dart'; import '../viewmodels/detail_viewmodel.dart'; class DetailView extends StatelessWidget { const DetailView({super.key}); @override Widget build(BuildContext context) { return ViewModelBuilder<DetailViewModel>.reactive( viewModelBuilder: () => DetailViewModel()..init(), builder: (context, viewModel, child) => Scaffold( appBar: AppBar(title: const Text('详情页')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('接收的参数:${viewModel.receivedData ?? '无'}'), const SizedBox(height: 20), ElevatedButton( onPressed: () => locator<NavigationService>().back(), child: const Text('返回'), ), ], ), ), ), ); } }
四、Dialog Service弹窗功能实现
1. 自定义弹窗样式(可选)
如果需要自定义弹窗外观,可在setupLocator中配置:
void setupLocator() { locator.registerLazySingleton(() => NavigationService()); locator.registerLazySingleton(() => DialogService( dialogBuilder: (context, request) => AlertDialog( title: Text(request.title ?? '提示'), content: Text(request.description ?? ''), actions: [ if (request.cancelTitle != null) TextButton( onPressed: () => locator<DialogService>().completeDialog(DialogResponse(confirmed: false)), child: Text(request.cancelTitle!), ), TextButton( onPressed: () => locator<DialogService>().completeDialog(DialogResponse(confirmed: true)), child: Text(request.mainButtonTitle ?? '确定'), ), ], ), )); }
2. ViewModel中调用弹窗
在HomeViewModel中添加弹窗调用方法:
class HomeViewModel extends BaseViewModel { final _navigationService = locator<NavigationService>(); final _dialogService = locator<DialogService>(); // 显示确认弹窗 void showConfirmDialog() async { final response = await _dialogService.showDialog( title: '确认跳转', description: '确定要进入详情页吗?', mainButtonTitle: '确定', cancelTitle: '取消', ); if (response?.confirmed == true) { navigateToDetail(); } } // 显示加载弹窗 void showLoading() { _dialogService.showLoadingDialog(title: '加载中...'); // 模拟异步任务完成后关闭弹窗 Future.delayed(const Duration(seconds: 2), () { _dialogService.completeDialog(); }); } }
修改HomeView的按钮点击事件为viewModel.showConfirmDialog()即可触发弹窗。
关键注意事项
- 所有服务必须通过
locator获取,确保单例性 - ViewModel继承
BaseViewModel,通过notifyListeners()触发UI更新 - 导航参数获取后需注意类型转换,避免空指针异常
- 弹窗操作结果通过
DialogResponse.confirmed判断用户选择
内容的提问来源于stack exchange,提问作者Priyank Shah
相关产品推荐
相关产品推荐

