如何使用Provider替代setState修改按钮颜色,避免地图组件不必要重绘
实现方案
1. 安装provider依赖
在项目pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter provider: ^6.1.1 # 可替换为当前最新稳定版
执行flutter pub get完成安装。
2. 新建状态管理类
创建独立的DriverStatusProvider类管理按钮相关状态:
import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; class DriverStatusProvider extends ChangeNotifier { // 初始状态默认离线 bool _isDriverAvailable = false; Color _driverStatusColor = Colors.black; String _driverStatusText = "您当前处于离线状态"; // 对外暴露只读的状态 bool get isDriverAvailable => _isDriverAvailable; Color get driverStatusColor => _driverStatusColor; String get driverStatusText => _driverStatusText; // 切换上下线状态的方法 void toggleDriverStatus({ required Function onOnline, // 上线时需要执行的业务逻辑 required Function onOffline, // 下线时需要执行的业务逻辑 }) { if (!_isDriverAvailable) { // 执行上线逻辑 onOnline(); // 更新状态 _isDriverAvailable = true; _driverStatusColor = Colors.green; _driverStatusText = "您当前处于在线状态"; } else { // 执行下线逻辑 onOffline(); // 更新状态 _isDriverAvailable = false; _driverStatusColor = Colors.black; _driverStatusText = "您当前处于离线状态"; } // 通知监听者更新 notifyListeners(); } }
3. 注册Provider
在当前页面的父层注册Provider,示例如下:
// 你原有页面的父组件处修改 ChangeNotifierProvider( create: (context) => DriverStatusProvider(), child: YourOriginalPage(), // 替换为你的原有页面类名 )
4. 修改原有页面代码
删除原有页面State中定义的driverStatusColor、driverStatusText、isDriverAvailable三个变量,修改build方法如下:
@override Widget build(BuildContext context) { super.build(context); return Stack( children: [ // CustomMap不在Provider监听范围内,永远不会被强制重建 const CustomMap(), Positioned( top: 60.0, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), // 用Selector仅监听需要的状态,仅更新按钮部分 child: Selector<DriverStatusProvider, (Color, String)>( selector: (context, provider) => (provider.driverStatusColor, provider.driverStatusText), builder: (context, status, child) { return RaisedButton( color: status.$1, child: Text(status.$2), onPressed: () { final provider = Provider.of<DriverStatusProvider>(context, listen: false); provider.toggleDriverStatus( onOnline: () { makeDriverOnlineNow(); getLocationLiveUpdates(); displayToastMessage("You are Online now", context); }, onOffline: () { driverOffline(); displayToastMessage("You are Offline now", context); }, ); }, ); }, ), ) ], ), ) ], ); }
实现原理
Selector只会监听你指定的driverStatusColor和driverStatusText两个状态,状态变化时仅会重建Selector包裹的按钮组件,位于监听范围外的CustomMap完全不会触发重建,也就不会出现地图重载的问题。
内容的提问来源于stack exchange,提问作者Pannam T
相关产品推荐
相关产品推荐

