Flutter:使用带有嵌套类的提供程序更新窗口小部件 [英] Flutter: Update widget using Provider with nested class

查看:107
本文介绍了Flutter:使用带有嵌套类的提供程序更新窗口小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Provider ,并且我尝试在方法被调用后更新我的窗口小部件一个ChangeNotifierProvider的嵌套对象(在嵌套在Aircraft中的Seat中调用updateColor()).

I am using Provider and I am trying to have my widgets updated once a method is called under a nested object of the ChangeNotifierProvider (calling updateColor() in Seat which is nested in Aircraft).

Flutter Provider嵌套对象问题所述,我尝试使用ChangeNotifierProxyProvider,但未成功.

As mentioned in Flutter Provider Nested Objects question, I tried using ChangeNotifierProxyProvider but without success.

当我调用updateColor()时,如何确保我的小部件已更新?

How can I ensure my widgets are updated when I call 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 设置为 ChangeNotifier 并在 Seat 中提供一种更改颜色的方法(一个 setter 就足够了):

Why are you making seat also a ChangeNotifier, it doesn't need to notifyListeners directly since it is nested and created inside Aircraft, so you need to only make Aircraft a ChangeNotifier and provide a method inside Seat to change color (a setter is enough) :

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');
  }
}

这篇关于Flutter:使用带有嵌套类的提供程序更新窗口小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆