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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:07:04