Flutter:使用带有嵌套 class 的 Provider 更新小部件
Flutter: Update widget using Provider with nested class
我正在使用 Provider 并且我试图在 ChangeNotifierProvider 的嵌套对象下调用方法后更新我的小部件(在嵌套在 Aircraft 中的 Seat 中调用 updateColor())。
如 中所述,我尝试使用 ChangeNotifierProxyProvider 但没有成功。
如何确保在调用 updateColor() 时我的小部件已更新?
代码示例:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
main() {
runApp(MultiProvider(providers: [
ChangeNotifierProvider<Aircraft>(create: (_) => Aircraft()),
], child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Consumer<Aircraft>(builder: (context, aircraft, _) {
return Column(
children: <Widget>[
Text('${aircraft.aircraftManufacturer.toString()}'),
Text('${aircraft.emptyWeight}'),
Text('${aircraft.length}'),
Column(
children: aircraft.seats.entries.map((seat) {
return Text(
'Row ${seat.key} is Class: ${seat.value.seatClass.toString()}, '
+ 'emergencyExitSeat: ${seat.value.emergencyExitSeat.toString()}, '
+ ' emergencyExitSeat: ${seat.value.seatColor.toString()},');
}).toList()),
Column(
children: aircraft.seats.entries.map((seat) {
return RaisedButton(
onPressed: () => seat.value.updateColor(),
child: Text('Change color for ${seat.key}'),
);
}).toList())
],
);
}),
),
),
);
}
}
enum Manufacturer { Airbus, Boeing, Embraer }
enum SeatClass { First, Business, Economy }
class Aircraft extends ChangeNotifier {
Manufacturer _aircraftManufacturer;
double _emptyWeight;
double _length;
Map<int, Seat> _seats;
Manufacturer get aircraftManufacturer => _aircraftManufacturer;
double get emptyWeight => _emptyWeight;
double get length => _length;
Map<int, Seat> get seats => _seats;
Aircraft() {
_aircraftManufacturer = Manufacturer.Airbus;
_emptyWeight = 190.0;
_length = 66.80;
_seats = new Map<int, Seat>();
_seats.putIfAbsent(
1, () => new Seat(SeatClass.First, false, Color(0xFF42A5F5)));
_seats.putIfAbsent(
2, () => new Seat(SeatClass.Business, false, Color(0xFF42A4F5)));
_seats.putIfAbsent(
3, () => new Seat(SeatClass.Economy, false, Color(0xFF42A3F5)));
_seats.putIfAbsent(
4, () => new Seat(SeatClass.Economy, true, Color(0xFF42A2F5)));
}
}
class Seat extends ChangeNotifier {
SeatClass _seatClass;
bool _emergencyExitSeat;
Color _seatColor;
Seat(SeatClass seatClass, bool emergencyExitSeat, Color seatColor) {
_seatClass = seatClass;
_emergencyExitSeat = emergencyExitSeat;
_seatColor = seatColor;
}
SeatClass get seatClass => _seatClass;
bool get emergencyExitSeat => _emergencyExitSeat;
Color get seatColor => _seatColor;
void updateColor() {
_seatColor = Color(0xFF9EB26E);
print('Color updated');
notifyListeners();
}
}
你为什么要把座位也做成 ChangeNotifier
,它不需要直接 notifyListeners
因为它是 嵌套的 和 在Aircraft
里面创建了,所以你只需要让Aircraft
变成ChangeNotifier
,并在Seat
里面提供一个改变颜色的方法(setter
够了):
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
main() {
runApp(MultiProvider(providers: [
ChangeNotifierProvider<Aircraft>(create: (_) => Aircraft()),
], child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Consumer<Aircraft>(builder: (context, aircraft, _) {
return Column(
children: <Widget>[
Text('${aircraft.aircraftManufacturer.toString()}'),
Text('${aircraft.emptyWeight}'),
Text('${aircraft.length}'),
Column(
children: aircraft.seats.entries.map((seat) {
return Text(
'Row ${seat.key} is Class: ${seat.value.seatClass.toString()}, '
+ 'emergencyExitSeat: ${seat.value.emergencyExitSeat.toString()}, '
+ ' emergencyExitSeat: ${seat.value.seatColor.toString()},');
}).toList()),
Column(
children: aircraft.seats.entries.map((seat) {
return RaisedButton(
onPressed: () => aircraft.onSeatColorUpdate(seat.value),
child: Text('Change color for ${seat.key}'),
);
}).toList())
],
);
}),
),
),
);
}
}
enum Manufacturer { Airbus, Boeing, Embraer }
enum SeatClass { First, Business, Economy }
class Aircraft extends ChangeNotifier {
Manufacturer _aircraftManufacturer;
double _emptyWeight;
double _length;
Map<int, Seat> _seats;
Manufacturer get aircraftManufacturer => _aircraftManufacturer;
double get emptyWeight => _emptyWeight;
double get length => _length;
Map<int, Seat> get seats => _seats;
Aircraft() {
_aircraftManufacturer = Manufacturer.Airbus;
_emptyWeight = 190.0;
_length = 66.80;
_seats = new Map<int, Seat>();
_seats.putIfAbsent(
1, () => new Seat(SeatClass.First, false, Color(0xFF42A5F5)));
_seats.putIfAbsent(
2, () => new Seat(SeatClass.Business, false, Color(0xFF42A4F5)));
_seats.putIfAbsent(
3, () => new Seat(SeatClass.Economy, false, Color(0xFF42A3F5)));
_seats.putIfAbsent(
4, () => new Seat(SeatClass.Economy, true, Color(0xFF42A2F5)));
}
void onSeatColorUpdate(Seat seat){//you should edit this method to accept color as parameter
seat.updateColor();//you should edit this method to accept color as parameter
notifyListeners();
}
}
class Seat {
SeatClass _seatClass;
bool _emergencyExitSeat;
Color _seatColor;
Seat(SeatClass seatClass, bool emergencyExitSeat, Color seatColor) {
_seatClass = seatClass;
_emergencyExitSeat = emergencyExitSeat;
_seatColor = seatColor;
}
SeatClass get seatClass => _seatClass;
bool get emergencyExitSeat => _emergencyExitSeat;
Color get seatColor => _seatColor;
void updateColor() {
_seatColor = Color(0xFF9EB26E);
print('updateColor in class seat');
}
}
我正在使用 Provider 并且我试图在 ChangeNotifierProvider 的嵌套对象下调用方法后更新我的小部件(在嵌套在 Aircraft 中的 Seat 中调用 updateColor())。
如
如何确保在调用 updateColor() 时我的小部件已更新?
代码示例:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
main() {
runApp(MultiProvider(providers: [
ChangeNotifierProvider<Aircraft>(create: (_) => Aircraft()),
], child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Consumer<Aircraft>(builder: (context, aircraft, _) {
return Column(
children: <Widget>[
Text('${aircraft.aircraftManufacturer.toString()}'),
Text('${aircraft.emptyWeight}'),
Text('${aircraft.length}'),
Column(
children: aircraft.seats.entries.map((seat) {
return Text(
'Row ${seat.key} is Class: ${seat.value.seatClass.toString()}, '
+ 'emergencyExitSeat: ${seat.value.emergencyExitSeat.toString()}, '
+ ' emergencyExitSeat: ${seat.value.seatColor.toString()},');
}).toList()),
Column(
children: aircraft.seats.entries.map((seat) {
return RaisedButton(
onPressed: () => seat.value.updateColor(),
child: Text('Change color for ${seat.key}'),
);
}).toList())
],
);
}),
),
),
);
}
}
enum Manufacturer { Airbus, Boeing, Embraer }
enum SeatClass { First, Business, Economy }
class Aircraft extends ChangeNotifier {
Manufacturer _aircraftManufacturer;
double _emptyWeight;
double _length;
Map<int, Seat> _seats;
Manufacturer get aircraftManufacturer => _aircraftManufacturer;
double get emptyWeight => _emptyWeight;
double get length => _length;
Map<int, Seat> get seats => _seats;
Aircraft() {
_aircraftManufacturer = Manufacturer.Airbus;
_emptyWeight = 190.0;
_length = 66.80;
_seats = new Map<int, Seat>();
_seats.putIfAbsent(
1, () => new Seat(SeatClass.First, false, Color(0xFF42A5F5)));
_seats.putIfAbsent(
2, () => new Seat(SeatClass.Business, false, Color(0xFF42A4F5)));
_seats.putIfAbsent(
3, () => new Seat(SeatClass.Economy, false, Color(0xFF42A3F5)));
_seats.putIfAbsent(
4, () => new Seat(SeatClass.Economy, true, Color(0xFF42A2F5)));
}
}
class Seat extends ChangeNotifier {
SeatClass _seatClass;
bool _emergencyExitSeat;
Color _seatColor;
Seat(SeatClass seatClass, bool emergencyExitSeat, Color seatColor) {
_seatClass = seatClass;
_emergencyExitSeat = emergencyExitSeat;
_seatColor = seatColor;
}
SeatClass get seatClass => _seatClass;
bool get emergencyExitSeat => _emergencyExitSeat;
Color get seatColor => _seatColor;
void updateColor() {
_seatColor = Color(0xFF9EB26E);
print('Color updated');
notifyListeners();
}
}
你为什么要把座位也做成 ChangeNotifier
,它不需要直接 notifyListeners
因为它是 嵌套的 和 在Aircraft
里面创建了,所以你只需要让Aircraft
变成ChangeNotifier
,并在Seat
里面提供一个改变颜色的方法(setter
够了):
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
main() {
runApp(MultiProvider(providers: [
ChangeNotifierProvider<Aircraft>(create: (_) => Aircraft()),
], child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Consumer<Aircraft>(builder: (context, aircraft, _) {
return Column(
children: <Widget>[
Text('${aircraft.aircraftManufacturer.toString()}'),
Text('${aircraft.emptyWeight}'),
Text('${aircraft.length}'),
Column(
children: aircraft.seats.entries.map((seat) {
return Text(
'Row ${seat.key} is Class: ${seat.value.seatClass.toString()}, '
+ 'emergencyExitSeat: ${seat.value.emergencyExitSeat.toString()}, '
+ ' emergencyExitSeat: ${seat.value.seatColor.toString()},');
}).toList()),
Column(
children: aircraft.seats.entries.map((seat) {
return RaisedButton(
onPressed: () => aircraft.onSeatColorUpdate(seat.value),
child: Text('Change color for ${seat.key}'),
);
}).toList())
],
);
}),
),
),
);
}
}
enum Manufacturer { Airbus, Boeing, Embraer }
enum SeatClass { First, Business, Economy }
class Aircraft extends ChangeNotifier {
Manufacturer _aircraftManufacturer;
double _emptyWeight;
double _length;
Map<int, Seat> _seats;
Manufacturer get aircraftManufacturer => _aircraftManufacturer;
double get emptyWeight => _emptyWeight;
double get length => _length;
Map<int, Seat> get seats => _seats;
Aircraft() {
_aircraftManufacturer = Manufacturer.Airbus;
_emptyWeight = 190.0;
_length = 66.80;
_seats = new Map<int, Seat>();
_seats.putIfAbsent(
1, () => new Seat(SeatClass.First, false, Color(0xFF42A5F5)));
_seats.putIfAbsent(
2, () => new Seat(SeatClass.Business, false, Color(0xFF42A4F5)));
_seats.putIfAbsent(
3, () => new Seat(SeatClass.Economy, false, Color(0xFF42A3F5)));
_seats.putIfAbsent(
4, () => new Seat(SeatClass.Economy, true, Color(0xFF42A2F5)));
}
void onSeatColorUpdate(Seat seat){//you should edit this method to accept color as parameter
seat.updateColor();//you should edit this method to accept color as parameter
notifyListeners();
}
}
class Seat {
SeatClass _seatClass;
bool _emergencyExitSeat;
Color _seatColor;
Seat(SeatClass seatClass, bool emergencyExitSeat, Color seatColor) {
_seatClass = seatClass;
_emergencyExitSeat = emergencyExitSeat;
_seatColor = seatColor;
}
SeatClass get seatClass => _seatClass;
bool get emergencyExitSeat => _emergencyExitSeat;
Color get seatColor => _seatColor;
void updateColor() {
_seatColor = Color(0xFF9EB26E);
print('updateColor in class seat');
}
}