以前我一直在使用提供程序,因为它很简单,但现在我想检查我们的
flutter_riverpod
我无法理解我拥有的一些代码,我想知道你是否可以帮助我将其转换为 flutter_river pod,这样我有一个主意
首先这是使用
provider
的项目
我有这样的主屏幕,可以从 firebase 获取数据
class _MainScreenState extends State<MainScreen> {
int _currentIndex = 0;
bool _isLoading = true;
final double smallScreenSize = 600;
final double largeScreenSize = 800;
final double smallIconSize = 18;
final double largeIconSize = 24;
Stream<List<Map<String, dynamic>>>? captainDataStream;
Stream<List<Map<String, dynamic>>>? firstOfficerDataStream;
Stream<List<Map<String, dynamic>>>? cabinCrewStream;
@override
void initState() {
//print('mainScreen initstate called');
super.initState();
_loadData();
}
Future<void> _loadData() async {
//await FirebaseServices.uploadInitialData();
await Provider.of<RosterDataProvider>(context, listen: false)
.getCaptainDatabase();
//use riverpod provider to get data
await Provider.of<RosterDataProvider>(context, listen: false)
.getFirstOfficerDatabase();
await Provider.of<RosterDataProvider>(context, listen: false)
.getCabinCrewDatabase();
setState(() {
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
现在在我的
changeNotifier
我有这样的
class RosterDataProvider extends ChangeNotifier {
final List<Map<String, dynamic>> _captainSnapShot = [];
final List<Map<String, dynamic>> _firstOfficerSnapShot = [];
final List<Map<String, dynamic>> _cabinCrewSnapShot = [];
final List<PlutoRow> _captainRows = [];
final List<PlutoRow> _firstOfficerRows = [];
final List<PlutoRow> _cabinCrewRows = [];
final List<PlutoColumn> _captainColumn = [];
PlutoGridMode _mode = PlutoGridMode.selectWithOneTap;
PlutoGridMode get mode => _mode;
List<Map<String, dynamic>> get captainSnapShot => _captainSnapShot;
List<Map<String, dynamic>> get firstOfficerSnapShot => _firstOfficerSnapShot;
List<Map<String, dynamic>> get cabinCrewSnapShot => _cabinCrewSnapShot;
List<PlutoRow> get captainRows => _captainRows;
List<PlutoRow> get firstOfficerRows => _firstOfficerRows;
List<PlutoRow> get cabinCrewRows => _cabinCrewRows;
List<PlutoColumn> get captainColumn => _captainColumn;
set mode(PlutoGridMode mode) {
_mode = mode;
notifyListeners();
}
void setCaptainRows(List<PlutoRow> row) {
print('setCaptainRows######');
_captainRows.clear();
_captainRows.addAll(row);
notifyListeners();
}
void setFirstOfficerRows(List<PlutoRow> row) {
_firstOfficerRows.clear();
_firstOfficerRows.addAll(row);
notifyListeners();
}
void setCabinCrewRows(List<PlutoRow> row) {
_cabinCrewRows.clear();
_cabinCrewRows.addAll(row);
notifyListeners();
}
Future<void> getCaptainDatabase() async {
final DatabaseReference databaseReference = FirebaseDatabase.instance.ref();
final captainNode = databaseReference.child('CAPTAIN_DATA');
try {
final event = await captainNode.once();
final captainData = event.snapshot.value as Map<dynamic, dynamic>;
captainData.entries.map((entry) {
final Map<String, dynamic> captain = {
'SN': entry.value['SN'] ?? 'ERR' as Map<String, dynamic>,
'NAME': entry.value['NAME'] ?? 'ERR' as Map<String, dynamic>,
'CODE': entry.value['CODE'] ?? 'ERR' as Map<String, dynamic>,
};
_captainSnapShot.add(captain);
return captain;
}).toList();
} catch (error) {
// print("Error loading data: $error");
}
notifyListeners();
}
Future<void> getFirstOfficerDatabase() async {
// print('reached captainDatabase Download');
final DatabaseReference databaseReference = FirebaseDatabase.instance.ref();
final firstOfficerNode = databaseReference.child('FIRST_OFFICER_DATA');
try {
final event = await firstOfficerNode.once();
final firstOfficerData = event.snapshot.value as Map<dynamic, dynamic>;
firstOfficerData.entries.map((entry) {
final Map<String, dynamic> firstOfficer = {
'SN': entry.value['SN'] ?? 'ERR' as Map<String, dynamic>,
'NAME': entry.value['NAME'] ?? 'ERR' as Map<String, dynamic>,
};
parseCommonNestedData(entry, firstOfficer);
_firstOfficerSnapShot.add(firstOfficer);
return firstOfficer;
}).toList();
} catch (error) {
// print("Error loading data: $error");
}
notifyListeners();
}
}
接下来我将在其他类中使用来自 RosterDataProvider 的数据,如下所示
class Leave extends StatefulWidget {
const Leave({super.key});
@override
State<Leave> createState() => _LeaveState();
}
class _LeaveState extends State<Leave> {
List<Map<String, dynamic>>? captainData;
List<Map<String, dynamic>>? firstOfficerData;
List<Map<String, dynamic>>? cabinCrewData;
PlutoGridStateManager? _stateManager;
List<Map<String, dynamic>>? dataCabin;
List<PlutoColumn>? columns;
List<PlutoRow>? plutoRows;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
captainData =
Provider.of<RosterDataProvider>(context, listen: false).captainSnapShot;
firstOfficerData = Provider.of<RosterDataProvider>(context, listen: false)
.firstOfficerSnapShot;
cabinCrewData = Provider.of<RosterDataProvider>(context, listen: false)
.cabinCrewSnapShot;
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: DefaultTabController(
length: 3,
child: Column(
children: [
const TabBar(
tabs: [
Tab(text: 'Captain Leave'),
Tab(text: 'First Officer Leave'),
Tab(text: 'Cabin Crew Leave'),
],
indicatorColor: Color.fromARGB(255, 102, 249, 4),
indicatorSize: TabBarIndicatorSize.label,
),
Expanded(
child: TabBarView(
children: [
buildGrid(captainData!, "captain"),
buildGrid(firstOfficerData!, "firstOfficer"),
buildGrid(cabinCrewData!, "cabinCrew"),
],
),
),
],
),
),
);
}
所以这就是正在发生的事情,主屏幕-->changenotifier-->离开,我无法在RiverPod中理解这个概念,我怎样才能实现这个确切的行为?
您需要将
RosterDataProvider
拆分为许多不同的 Riverpod 提供者,并定义不同的方法来更改每个提供者的逻辑。对于简单数据类型,请使用 StateProvider
,对于集合,请使用 NotifierProvider
。例如,让我展示一个简单的案例 PlutoGridMode
:
final plutoGridModeProvider = StateProvider((_) => PlutoGridMode.selectWithOneTap);
现在在你的小部件中:
class PlutoGridModeWidget extends ConsumerWidget {
@override
Widget build(BuildContext context) {
final mode = ref.watch(plutoGridModeProvider);
return (
children: [
ElevatedButton(
child: Text('New mode'),
onPressed: () =>
ref.read(plutoGridModeProvider.notifier).update((oldState) => PlutoGridMode.selectAll)},
),
const SizedBox(width: 10),
],
);
}
}
只要您单击按钮(在此示例中一次:),您的小部件就会自行重建。
如果需要异步[数据|加载|错误]状态,也可以考虑使用
AsyncNotifier
,或者将Notifier
与必要的密封类一起使用。这里有一个很好的例子: