在这里插入图片描述
在这里插入图片描述

作者:付文龙(红目香薰)
仓库地址https://gitcode.com/feng8403000/FlutterfromBeginnertoAdvancedForHarmonyOS.git
联系邮箱:372699828@qq.com

引言

Riverpod作为新一代状态管理方案,与Flutter框架的集成非常紧密。本文将详细介绍Riverpod与Flutter框架的完整集成方案,包括入口配置、路由集成、主题管理、导航守卫等高级特性,帮助开发者在鸿蒙平台开发Flutter应用时实现优雅的状态管理集成。

入口配置

基本集成

import "package:flutter/material.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      title: "Flutter Riverpod应用",
      home: HomePage(),
    );
  }
}

配置overrides

void main() {
  runApp(
    ProviderScope(
      overrides: [
        apiProvider.overrideWithValue(ApiServiceImpl()),
        storageProvider.overrideWithValue(StorageServiceImpl()),
      ],
      child: MyApp(),
    ),
  );
}

配置observers

void main() {
  runApp(
    ProviderScope(
      observers: [
        ProviderLogger(),
      ],
      child: MyApp(),
    ),
  );
}

class ProviderLogger extends ProviderObserver {
  
  void didUpdateProvider(
    ProviderBase provider,
    Object? previousValue,
    Object? newValue,
    ProviderContainer container,
  ) {
    print("Provider更新: ${provider.name}, 旧值: $previousValue, 新值: $newValue");
  }
}

路由集成

基本路由配置

class MyApp extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      title: "Flutter Riverpod应用",
      initialRoute: "/",
      routes: {
        "/": (context) => const HomePage(),
        "/cart": (context) => const CartPage(),
        "/profile": (context) => const ProfilePage(),
        "/login": (context) => const LoginPage(),
      },
    );
  }
}

动态路由配置

class MyApp extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final authState = ref.watch(authProvider);
    
    return MaterialApp(
      title: "Flutter Riverpod应用",
      initialRoute: authState.isAuthenticated ? "/" : "/login",
      onGenerateRoute: (settings) {
        switch (settings.name) {
          case "/":
            return MaterialPageRoute(builder: (_) => HomePage());
          case "/cart":
            return MaterialPageRoute(builder: (_) => CartPage());
          case "/product/:id":
            final id = settings.arguments as String? ?? "";
            return MaterialPageRoute(builder: (_) => ProductDetailPage(id: id));
          default:
            return MaterialPageRoute(builder: (_) => NotFoundPage());
        }
      },
    );
  }
}

导航守卫

class MyApp extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      title: "Flutter Riverpod应用",
      onGenerateRoute: (settings) {
        final isAuthenticated = ref.read(isAuthenticatedProvider);
        
        // 需要登录的页面
        if (["/cart", "/profile", "/orders"].contains(settings.name)) {
          if (!isAuthenticated) {
            return MaterialPageRoute(builder: (_) => LoginPage());
          }
        }
        
        // 已登录用户访问登录页自动跳转
        if (settings.name == "/login" && isAuthenticated) {
          return MaterialPageRoute(builder: (_) => HomePage());
        }
        
        // 正常路由
        return _generateRoute(settings);
      },
    );
  }
  
  Route<dynamic>? _generateRoute(RouteSettings settings) {
    switch (settings.name) {
      case "/":
        return MaterialPageRoute(builder: (_) => HomePage());
      case "/cart":
        return MaterialPageRoute(builder: (_) => CartPage());
      case "/profile":
        return MaterialPageRoute(builder: (_) => ProfilePage());
      case "/login":
        return MaterialPageRoute(builder: (_) => LoginPage());
      default:
        return MaterialPageRoute(builder: (_) => NotFoundPage());
    }
  }
}

主题管理

动态主题配置

final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.system);

final primaryColorProvider = StateProvider<Color>((ref) => Colors.blue);

final themeProvider = Provider<ThemeData>((ref) {
  final themeMode = ref.watch(themeModeProvider);
  final primaryColor = ref.watch(primaryColorProvider);
  
  return ThemeData(
    primaryColor: primaryColor,
    brightness: themeMode == ThemeMode.dark ? Brightness.dark : Brightness.light,
    useMaterial3: true,
    colorScheme: ColorScheme.fromSeed(
      seedColor: primaryColor,
      brightness: themeMode == ThemeMode.dark ? Brightness.dark : Brightness.light,
    ),
  );
});

class MyApp extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final theme = ref.watch(themeProvider);
    
    return MaterialApp(
      title: "Flutter Riverpod应用",
      theme: theme,
      home: HomePage(),
    );
  }
}

主题切换页面

class SettingsPage extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final themeMode = ref.watch(themeModeProvider);
    final primaryColor = ref.watch(primaryColorProvider);
    
    return Scaffold(
      appBar: AppBar(title: const Text("设置")),
      body: ListView(
        children: [
          ListTile(
            title: const Text("主题模式"),
            subtitle: Text(themeMode.name),
            trailing: DropdownButton<ThemeMode>(
              value: themeMode,
              items: const [
                DropdownMenuItem(value: ThemeMode.system, child: Text("系统")),
                DropdownMenuItem(value: ThemeMode.light, child: Text("浅色")),
                DropdownMenuItem(value: ThemeMode.dark, child: Text("深色")),
              ],
              onChanged: (value) {
                if (value != null) {
                  ref.read(themeModeProvider.notifier).state = value;
                }
              },
            ),
          ),
          ListTile(
            title: const Text("主题颜色"),
            trailing: Wrap(
              spacing: 8,
              children: [
                _colorButton(context, ref, Colors.blue),
                _colorButton(context, ref, Colors.green),
                _colorButton(context, ref, Colors.red),
                _colorButton(context, ref, Colors.purple),
                _colorButton(context, ref, Colors.orange),
              ],
            ),
          ),
        ],
      ),
    );
  }
  
  Widget _colorButton(BuildContext context, WidgetRef ref, Color color) {
    final currentColor = ref.watch(primaryColorProvider);
    
    return InkWell(
      onTap: () => ref.read(primaryColorProvider.notifier).state = color,
      borderRadius: BorderRadius.circular(50),
      child: Container(
        width: 40,
        height: 40,
        decoration: BoxDecoration(
          color: color,
          borderRadius: BorderRadius.circular(50),
          border: Border.all(
            color: currentColor == color ? Colors.white : Colors.transparent,
            width: 3,
          ),
          boxShadow: [
            if (currentColor == color)
              BoxShadow(color: color, blurRadius: 10),
          ],
        ),
      ),
    );
  }
}

状态持久化

SharedPreferences集成

import "package:shared_preferences/shared_preferences.dart";

final sharedPreferencesProvider = FutureProvider<SharedPreferences>((ref) async {
  return await SharedPreferences.getInstance();
});

final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.system);

class ThemeNotifier extends StateNotifier<ThemeMode> {
  ThemeNotifier(this.ref) : super(ThemeMode.system) {
    _loadThemeMode();
  }
  
  final Ref ref;
  
  Future<void> _loadThemeMode() async {
    final prefs = await ref.read(sharedPreferencesProvider.future);
    final savedMode = prefs.getString("theme_mode");
    if (savedMode != null) {
      state = ThemeMode.values.firstWhere(
        (mode) => mode.name == savedMode,
        orElse: () => ThemeMode.system,
      );
    }
  }
  
  Future<void> setThemeMode(ThemeMode mode) async {
    state = mode;
    final prefs = await ref.read(sharedPreferencesProvider.future);
    await prefs.setString("theme_mode", mode.name);
  }
}

final themeNotifierProvider = StateNotifierProvider<ThemeNotifier, ThemeMode>((ref) {
  return ThemeNotifier(ref);
});

购物车持久化

import "dart:convert";

final cartProvider = StateNotifierProvider<CartNotifier, List<CartItem>>((ref) {
  return CartNotifier(ref);
});

class CartNotifier extends StateNotifier<List<CartItem>> {
  CartNotifier(this.ref) : super([]) {
    _loadCart();
  }
  
  final Ref ref;
  
  Future<void> _loadCart() async {
    final prefs = await ref.read(sharedPreferencesProvider.future);
    final savedCart = prefs.getString("cart");
    if (savedCart != null) {
      final List<dynamic> jsonList = jsonDecode(savedCart);
      state = jsonList.map((json) => CartItem.fromJson(json)).toList();
    }
  }
  
  Future<void> _saveCart() async {
    final prefs = await ref.read(sharedPreferencesProvider.future);
    final jsonList = state.map((item) => item.toJson()).toList();
    await prefs.setString("cart", jsonEncode(jsonList));
  }
  
  void addItem(CartItem item) {
    final existingIndex = state.indexWhere((i) => i.id == item.id);
    if (existingIndex >= 0) {
      final newState = List<CartItem>.from(state);
      newState[existingIndex] = newState[existingIndex].copyWith(
        quantity: newState[existingIndex].quantity + 1,
      );
      state = newState;
    } else {
      state = [...state, item];
    }
    _saveCart();
  }
  
  void removeItem(String id) {
    state = state.where((item) => item.id != id).toList();
    _saveCart();
  }
  
  void clear() {
    state = [];
    _saveCart();
  }
}

class CartItem {
  final String id;
  final String name;
  final double price;
  final int quantity;
  
  CartItem({
    required this.id,
    required this.name,
    required this.price,
    this.quantity = 1,
  });
  
  CartItem copyWith({int? quantity}) {
    return CartItem(
      id: id,
      name: name,
      price: price,
      quantity: quantity ?? this.quantity,
    );
  }
  
  Map<String, dynamic> toJson() {
    return {
      "id": id,
      "name": name,
      "price": price,
      "quantity": quantity,
    };
  }
  
  factory CartItem.fromJson(Map<String, dynamic> json) {
    return CartItem(
      id: json["id"],
      name: json["name"],
      price: json["price"],
      quantity: json["quantity"],
    );
  }
}

核心集成示例

示例1:完整的认证与路由集成

// 认证Provider
enum AuthStatus { loading, authenticated, unauthenticated }

class AuthState {
  final AuthStatus status;
  final User? user;
  final String? error;
  
  AuthState({required this.status, this.user, this.error});
  
  AuthState copyWith({AuthStatus? status, User? user, String? error}) {
    return AuthState(
      status: status ?? this.status,
      user: user ?? this.user,
      error: error ?? this.error,
    );
  }
}

class AuthNotifier extends StateNotifier<AuthState> {
  AuthNotifier(this.ref) : super(AuthState(status: AuthStatus.loading)) {
    _checkAuth();
  }
  
  final Ref ref;
  
  Future<void> _checkAuth() async {
    final prefs = await ref.read(sharedPreferencesProvider.future);
    final token = prefs.getString("auth_token");
    
    if (token != null) {
      try {
        final user = await ref.read(apiProvider).getCurrentUser(token);
        state = state.copyWith(status: AuthStatus.authenticated, user: user);
      } catch (_) {
        await prefs.remove("auth_token");
        state = state.copyWith(status: AuthStatus.unauthenticated);
      }
    } else {
      state = state.copyWith(status: AuthStatus.unauthenticated);
    }
  }
  
  Future<void> login(String email, String password) async {
    state = state.copyWith(status: AuthStatus.loading, error: null);
    
    try {
      final token = await ref.read(apiProvider).login(email, password);
      final prefs = await ref.read(sharedPreferencesProvider.future);
      await prefs.setString("auth_token", token);
      
      final user = await ref.read(apiProvider).getCurrentUser(token);
      state = state.copyWith(status: AuthStatus.authenticated, user: user);
    } catch (e) {
      state = state.copyWith(
        status: AuthStatus.unauthenticated,
        error: e.toString(),
      );
    }
  }
  
  Future<void> logout() async {
    final prefs = await ref.read(sharedPreferencesProvider.future);
    await prefs.remove("auth_token");
    state = state.copyWith(status: AuthStatus.unauthenticated, user: null);
  }
}

final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) {
  return AuthNotifier(ref);
});

final isAuthenticatedProvider = Provider<bool>((ref) {
  return ref.watch(authProvider).status == AuthStatus.authenticated;
});

// 应用入口
class MyApp extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final authState = ref.watch(authProvider);
    final theme = ref.watch(themeProvider);
    
    // 加载中状态
    if (authState.status == AuthStatus.loading) {
      return MaterialApp(
        home: Scaffold(
          body: Center(child: CircularProgressIndicator()),
        ),
      );
    }
    
    return MaterialApp(
      title: "Flutter Riverpod应用",
      theme: theme,
      initialRoute: authState.status == AuthStatus.authenticated ? "/" : "/login",
      onGenerateRoute: (settings) => _generateRoute(context, ref, settings),
    );
  }
  
  Route<dynamic> _generateRoute(
    BuildContext context,
    WidgetRef ref,
    RouteSettings settings,
  ) {
    final isAuthenticated = ref.read(isAuthenticatedProvider);
    
    // 登录守卫
    if (["/cart", "/profile", "/orders"].contains(settings.name) && !isAuthenticated) {
      return MaterialPageRoute(builder: (_) => LoginPage());
    }
    
    // 已登录用户访问登录页
    if (settings.name == "/login" && isAuthenticated) {
      return MaterialPageRoute(builder: (_) => HomePage());
    }
    
    // 正常路由
    switch (settings.name) {
      case "/":
        return MaterialPageRoute(builder: (_) => HomePage());
      case "/cart":
        return MaterialPageRoute(builder: (_) => CartPage());
      case "/profile":
        return MaterialPageRoute(builder: (_) => ProfilePage());
      case "/orders":
        return MaterialPageRoute(builder: (_) => OrdersPage());
      case "/login":
        return MaterialPageRoute(builder: (_) => LoginPage());
      case "/product/:id":
        final id = settings.arguments as String? ?? "";
        return MaterialPageRoute(builder: (_) => ProductDetailPage(id: id));
      default:
        return MaterialPageRoute(builder: (_) => NotFoundPage());
    }
  }
}

// 登录页面
class LoginPage extends ConsumerWidget {
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  
  
  Widget build(BuildContext context, WidgetRef ref) {
    final authState = ref.watch(authProvider);
    final authNotifier = ref.read(authProvider.notifier);
    
    return Scaffold(
      appBar: AppBar(title: const Text("登录")),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: _emailController,
              decoration: const InputDecoration(labelText: "邮箱"),
              enabled: authState.status != AuthStatus.loading,
            ),
            TextField(
              controller: _passwordController,
              decoration: const InputDecoration(labelText: "密码"),
              obscureText: true,
              enabled: authState.status != AuthStatus.loading,
            ),
            const SizedBox(height: 16),
            if (authState.status == AuthStatus.loading)
              const CircularProgressIndicator()
            else if (authState.error != null)
              Text(authState.error!, style: TextStyle(color: Colors.red))
            else
              ElevatedButton(
                onPressed: () {
                  authNotifier.login(
                    _emailController.text,
                    _passwordController.text,
                  );
                },
                child: const Text("登录"),
              ),
          ],
        ),
      ),
    );
  }
}

// 首页
class HomePage extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final user = ref.watch(authProvider.select((state) => state.user));
    final cartItemCount = ref.watch(cartItemCountProvider);
    
    return Scaffold(
      appBar: AppBar(title: const Text("首页")),
      body: Center(
        child: Column(
          children: [
            Text("欢迎, ${user?.name ?? "用户"}!"),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, "/cart"),
              child: Text("购物车 ($cartItemCount)"),
            ),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, "/profile"),
              child: const Text("个人中心"),
            ),
          ],
        ),
      ),
      drawer: Drawer(
        child: ListView(
          children: [
            DrawerHeader(child: Text("欢迎, ${user?.name}")),
            ListTile(
              title: const Text("购物车"),
              onTap: () => Navigator.pushNamed(context, "/cart"),
            ),
            ListTile(
              title: const Text("订单"),
              onTap: () => Navigator.pushNamed(context, "/orders"),
            ),
            ListTile(
              title: const Text("设置"),
              onTap: () => Navigator.pushNamed(context, "/settings"),
            ),
            ListTile(
              title: const Text("退出登录"),
              onTap: () => ref.read(authProvider.notifier).logout(),
            ),
          ],
        ),
      ),
    );
  }
}

示例2:异步数据加载与缓存

final apiProvider = Provider<ApiService>((ref) => ApiServiceImpl());

final postsProvider = FutureProvider<List<Post>>((ref) async {
  final api = ref.read(apiProvider);
  return await api.getPosts();
});

final postsWithCacheProvider = FutureProvider<List<Post>>((ref) async {
  final api = ref.read(apiProvider);
  
  // 先尝试读取缓存
  final prefs = await ref.read(sharedPreferencesProvider.future);
  final cachedPosts = prefs.getString("posts");
  
  if (cachedPosts != null) {
    final List<dynamic> jsonList = jsonDecode(cachedPosts);
    final posts = jsonList.map((json) => Post.fromJson(json)).toList();
    
    // 在后台刷新数据
    ref.listenSelf((previous, next) {
      // 数据更新时自动缓存
      if (next.hasValue && next.value != null) {
        _cachePosts(prefs, next.value!);
      }
    });
    
    return posts;
  }
  
  // 无缓存,从网络获取
  final posts = await api.getPosts();
  await _cachePosts(prefs, posts);
  
  return posts;
});

Future<void> _cachePosts(SharedPreferences prefs, List<Post> posts) async {
  final jsonList = posts.map((post) => post.toJson()).toList();
  await prefs.setString("posts", jsonEncode(jsonList));
}

class PostListPage extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final posts = ref.watch(postsWithCacheProvider);
    
    return Scaffold(
      appBar: AppBar(title: const Text("帖子列表")),
      body: posts.when(
        data: (posts) {
          return RefreshIndicator(
            onRefresh: () async {
              ref.invalidate(postsWithCacheProvider);
              await ref.read(postsWithCacheProvider.future);
            },
            child: ListView.builder(
              itemCount: posts.length,
              itemBuilder: (context, index) {
                final post = posts[index];
                return ListTile(
                  title: Text(post.title),
                  subtitle: Text(post.content),
                  onTap: () => Navigator.pushNamed(context, "/post/${post.id}"),
                );
              },
            ),
          );
        },
        loading: () => const Center(child: CircularProgressIndicator()),
        error: (error, stack) => Center(child: Text("加载失败: $error")),
      ),
    );
  }
}

class Post {
  final String id;
  final String title;
  final String content;
  
  Post({required this.id, required this.title, required this.content});
  
  Map<String, dynamic> toJson() {
    return {"id": id, "title": title, "content": content};
  }
  
  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      id: json["id"],
      title: json["title"],
      content: json["content"],
    );
  }
}

示例3:Tab导航与状态管理

final currentTabProvider = StateProvider<int>((ref) => 0);

final tabPages = [
  HomePage(),
  CartPage(),
  ProfilePage(),
];

final tabTitles = ["首页", "购物车", "个人中心"];

final tabIcons = [
  Icons.home,
  Icons.shopping_cart,
  Icons.person,
];

class MainPage extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final currentTab = ref.watch(currentTabProvider);
    final cartItemCount = ref.watch(cartItemCountProvider);
    
    return Scaffold(
      body: tabPages[currentTab],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: currentTab,
        onTap: (index) => ref.read(currentTabProvider.notifier).state = index,
        items: [
          BottomNavigationBarItem(
            icon: const Icon(Icons.home),
            label: tabTitles[0],
          ),
          BottomNavigationBarItem(
            icon: Badge(
              label: Text("$cartItemCount"),
              isLabelVisible: cartItemCount > 0,
              child: const Icon(Icons.shopping_cart),
            ),
            label: tabTitles[1],
          ),
          BottomNavigationBarItem(
            icon: const Icon(Icons.person),
            label: tabTitles[2],
          ),
        ],
      ),
    );
  }
}

性能优化集成

懒加载Provider

final userProvider = FutureProvider.autoDispose<User>((ref) async {
  final api = ref.read(apiProvider);
  return await api.getUser();
});

class UserWidget extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final user = ref.watch(userProvider);
    
    return user.when(
      data: (user) => Text(user.name),
      loading: () => const CircularProgressIndicator(),
      error: (error, stack) => Text("错误: $error"),
    );
  }
}

选择性监听

class UserProfileWidget extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    // 只监听用户名变化
    final userName = ref.watch(userProvider.select((user) => user?.name ?? ""));
    
    return Text(userName);
  }
}

使用keepAlive缓存

final userProvider = FutureProvider.autoDispose<User>((ref) async {
  ref.keepAlive(); // 保持活跃,不自动销毁
  final api = ref.read(apiProvider);
  return await api.getUser();
});

鸿蒙平台特别考虑

平台适配配置

void main() {
  runApp(
    ProviderScope(
      overrides: [
        platformProvider.overrideWithValue(PlatformInfo()),
      ],
      child: MyApp(),
    ),
  );
}

final platformProvider = Provider<PlatformInfo>((ref) => PlatformInfo());

class PlatformInfo {
  bool get isHarmonyOS => false;
  
  String get platformName => "Android";
}

// 鸿蒙平台实现
class HarmonyOSPlatformInfo extends PlatformInfo {
  
  bool get isHarmonyOS => true;
  
  
  String get platformName => "HarmonyOS";
}

权限管理集成

final permissionProvider = StateNotifierProvider<PermissionNotifier, PermissionState>((ref) {
  return PermissionNotifier();
});

class PermissionState {
  final bool hasStoragePermission;
  final bool hasCameraPermission;
  
  PermissionState({
    required this.hasStoragePermission,
    required this.hasCameraPermission,
  });
  
  PermissionState copyWith({bool? hasStoragePermission, bool? hasCameraPermission}) {
    return PermissionState(
      hasStoragePermission: hasStoragePermission ?? this.hasStoragePermission,
      hasCameraPermission: hasCameraPermission ?? this.hasCameraPermission,
    );
  }
}

class PermissionNotifier extends StateNotifier<PermissionState> {
  PermissionNotifier() : super(PermissionState(
    hasStoragePermission: false,
    hasCameraPermission: false,
  ));
  
  Future<void> requestStoragePermission() async {
    // 鸿蒙平台权限请求
    state = state.copyWith(hasStoragePermission: true);
  }
  
  Future<void> requestCameraPermission() async {
    // 鸿蒙平台权限请求
    state = state.copyWith(hasCameraPermission: true);
  }
  
  Future<void> checkPermissions() async {
    // 检查已有的权限
    state = state.copyWith(
      hasStoragePermission: true,
      hasCameraPermission: true,
    );
  }
}

最佳实践

1. Provider分层管理

// 服务层Provider
final apiProvider = Provider<ApiService>((ref) => ApiServiceImpl());
final storageProvider = Provider<StorageService>((ref) => StorageServiceImpl());

// 状态层Provider
final authProvider = StateNotifierProvider<AuthNotifier, AuthState>((ref) => AuthNotifier(ref));
final cartProvider = StateNotifierProvider<CartNotifier, List<CartItem>>((ref) => CartNotifier(ref));

// 计算层Provider
final isAuthenticatedProvider = Provider<bool>((ref) {
  return ref.watch(authProvider).status == AuthStatus.authenticated;
});

final cartTotalProvider = Provider<double>((ref) {
  final cart = ref.watch(cartProvider);
  return cart.fold(0, (sum, item) => sum + item.price * item.quantity);
});

2. 使用Consumer减少重建

class CartPage extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final cart = ref.watch(cartProvider);
    
    return Scaffold(
      appBar: AppBar(title: const Text("购物车")),
      body: cart.isEmpty
          ? const Center(child: Text("购物车为空"))
          : ListView.builder(
              itemCount: cart.length,
              itemBuilder: (context, index) {
                final item = cart[index];
                return Consumer(
                  cartProvider,
                  (context, cart, child) {
                    return ListTile(
                      title: Text(item.name),
                      subtitle: Text(${item.price}"),
                    );
                  },
                );
              },
            ),
    );
  }
}

3. 异步状态处理统一

class UserWidget extends ConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final user = ref.watch(userProvider);
    
    return user.when(
      data: (user) => UserProfile(user: user),
      loading: () => const Center(child: CircularProgressIndicator()),
      error: (error, stack) => ErrorWidget(error),
    );
  }
}

class UserProfile extends StatelessWidget {
  final User user;
  
  const UserProfile({super.key, required this.user});
  
  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(user.name),
        Text(user.email),
      ],
    );
  }
}

总结

Riverpod与Flutter框架的集成是一个系统性的过程,涉及多个方面:

  1. 入口配置:使用ProviderScope包裹应用,配置overrides和observers。
  2. 路由集成:支持静态路由和动态路由,实现导航守卫。
  3. 主题管理:动态配置主题模式和颜色,支持主题切换。
  4. 状态持久化:与SharedPreferences集成,实现状态保存和恢复。
  5. 性能优化:使用autoDispose、select、keepAlive等特性优化性能。
  6. 鸿蒙适配:处理平台差异,实现权限管理等平台特定功能。

通过合理的集成方案,可以构建出结构清晰、性能优异的Flutter应用,特别是在鸿蒙平台开发时,这些集成方案将帮助开发者更好地利用Riverpod的强大功能。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐