You need to enable JavaScript to run this app. 基于Provider 5实现Flutter登录场景加载页展示的方案咨询
优惠活动
大模型
产品
解决方案
定价
更多

基于Provider 5实现Flutter登录场景加载页展示的方案咨询

基于Provider 5实现登录加载逻辑方案

1. 定义业务状态类

继承ChangeNotifier封装加载状态和登录逻辑,所有状态变更统一在类内处理:

import 'package:flutter/foundation.dart';

class AuthViewModel extends ChangeNotifier {
  // 私有变量存储加载状态,避免外部直接修改
  bool _isLoading = false;
  // 对外暴露只读的加载状态
  bool get isLoading => _isLoading;

  Future<void> login(String account, String password) async {
    // 输入校验不通过直接返回
    if (account.trim().isEmpty || password.trim().isEmpty) return;

    // 校验通过开启加载状态,通知监听者刷新UI
    _isLoading = true;
    notifyListeners();

    try {
      // 此处替换为实际的登录请求、用户信息持久化逻辑
      await Future.delayed(const Duration(seconds: 2)); // 模拟接口请求耗时
      // 登录成功后可执行路由跳转逻辑
    } catch (err) {
      // 可在此处添加登录失败的提示逻辑
      if (kDebugMode) print("登录异常:$err");
    } finally {
      // 无论请求成功/失败都关闭加载状态
      _isLoading = false;
      notifyListeners();
    }
  }
}

2. 全局注册状态实例

在应用入口处注册ChangeNotifierProvider,让子树可以访问到AuthViewModel实例:

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => AuthViewModel(),
      child: const MyApp(),
    ),
  );
}

3. 登录页绑定状态

使用StatelessWidget即可实现需求,通过Selector精准监听加载状态变化,控制页面渲染逻辑:

import 'package:provider/provider.dart';

class LoginPage extends StatelessWidget {
  const LoginPage({super.key});

  @override
  Widget build(BuildContext context) {
    // 用read获取ViewModel实例,点击事件不需要监听状态变化,性能更优
    final authViewModel = context.read<AuthViewModel>();
    final accountController = TextEditingController();
    final pwdController = TextEditingController();

    // Selector只监听isLoading字段的变化,避免不必要的UI重绘
    return Selector<AuthViewModel, bool>(
      selector: (_, vm) => vm.isLoading,
      builder: (_, isLoading, __) {
        return isLoading 
          ? const LoadingPage() 
          : Scaffold(
            appBar: AppBar(title: const Text("登录")),
            body: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  TextField(
                    controller: accountController,
                    decoration: const InputDecoration(hintText: "请输入账号"),
                  ),
                  const SizedBox(height: 12),
                  TextField(
                    controller: pwdController,
                    decoration: const InputDecoration(hintText: "请输入密码"),
                    obscureText: true,
                  ),
                  const SizedBox(height: 24),
                  ElevatedButton(
                    onPressed: () => authViewModel.login(
                      accountController.text,
                      pwdController.text,
                    ),
                    child: const Text("登录"),
                  )
                ],
              ),
            ),
          );
      },
    );
  }
}

4. 基于flutter_spinKit实现加载页

import 'package:flutter_spinkit/flutter_spinkit.dart';

class LoadingPage extends StatelessWidget {
  const LoadingPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: SpinKitFadingCircle(
          color: Colors.blueAccent,
          size: 48,
        ),
      ),
    );
  }
}
Flutter状态管理实操建议
  • 拆分状态粒度:不要将全业务状态塞到同一个ChangeNotifier中,按模块拆分状态类,比如用户模块、订单模块分别维护各自的状态,减少不必要的刷新范围
  • 优先用Selector替代Consumer:如果只需要监听状态中的某几个字段,用Selector可以精准控制刷新范围,性能远高于全量监听的Consumer
  • 逻辑收拢到状态类:UI层只负责事件触发和状态渲染,所有异步请求、数据校验、状态变更逻辑都统一放到对应的ChangeNotifier中,降低耦合度,也方便后续单元测试
  • 及时清理资源:在ChangeNotifier的dispose方法中取消未完成的异步请求、销毁流订阅,避免内存泄漏
  • 避免嵌套地狱:如果需要注册多个Provider,使用MultiProvider来统一管理,提升代码可读性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 10:36:07