如何将数据从有状态小部件传递到状态以确保小部件数据可用?

时间:2021-01-30 20:54:26

标签: flutter dart

我从一个有状态的小部件传递数据,我像在这个例子中一样访问它 (widget.variable)

https://stackoverflow.com/a/50818870/806009

但是,在此比较中,偶尔会为一行抛出错误(大约 20 分之一)

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The method '>' was called on null.
Receiver: null
Tried calling: >(10)

if (widget.x > 10){...}

目前似乎不知道widget.x。我是否应该使用 initState 来确保值“准备好”?

比如

  @override
  void initState() {
    super.initState();
    this.x = widget.x
  }

完整代码

class PlayerSelection extends StatefulWidget {
  final int teamId;
  final int leagueId;
  final League.League league;
  final String className;
  List<PlayerObj> playersListOfClass;
  final int index;
  final int remaining;

  PlayerSelection({Key key, @required this.teamId, this.leagueId, this.league, this.className, this.playersListOfClass, this.index, this.remaining}) : super(key: key);

  @override
  _PlayerSelection createState() => _PlayerSelection();
}

class _PlayerSelection extends State<PlayerSelection> {
  var playerWidgets = <Widget>[];
  List<PlayerObj> selectedPlayers = [];
  List<PlayerObj> playerList = [];
  PlayerObj draftedPlayer;
  List<PlayerClass> playerClassList = [];
  bool _isFavorited = false;
  Modal modal = new Modal();
  int lineupWeek = 0;
  int lineupSize = 0;
  String intervalLabel = '';
  bool _is_full = false;
  bool _is_locked = false;
  int remaining = 0;
  var currentColor = Colors.black;
  var rejectedPlayerId;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      resizeToAvoidBottomPadding: false,
      appBar: globals.MyAppBar(
          leading: IconButton(icon: Icon(Icons.close),
              onPressed: (){
                Navigator.pop(context, {'player': null,'index': this.widget.index});
          }), // go to league route,),
          title: Text(widget.className)
      ),
      body: Container(
        child: Column(children: [Expanded(child: ListView(children: _getLineup(this.widget.playersListOfClass))),]),
      ),
    );
  }


  List<Widget>_getLineup(playerList) {
    List<Widget> widgets = [];
    var index = 0;
    playerList.forEach((player) =>
        widgets.add(
            Padding(
              padding: const EdgeInsets.symmetric(horizontal:16.0),
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.white,
                  border: Border(
                    bottom: BorderSide(width: 1.0, color: Colors.grey.withOpacity(0.3)),
                  ),
                ),
                child: new ListTile(
                  leading: GestureDetector(
                    onTap: (){
                      if(!_is_full) {
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) =>
                              Players.PlayerDetail(playerId: player.playerId,
                                  leagueId: widget.leagueId,
                                  playerName: player.playerName,
                                  playerBio: player.playerBio)),
                        );
                      }
                    },
                    child: ClipOval(
                      child: _playerPicWidget(player)
                    ),
                  ),
                  title: GestureDetector(
                      onTap: (){
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) =>
                              Players.PlayerDetail(playerId: player.playerId,
                                  leagueId: widget.leagueId,
                                  playerName: player.playerName,
                                  playerBio: player.playerBio)),
                        );

                      },
                      child: _playerNameWidget(player)
                  ),
                  trailing: _trailingWidget(player),
                  onTap: () => player.playerPrice <= widget.remaining ? Navigator.pop(context, {'player': player,'index': this.widget.index}) : null,

                   // return player back
                ),
              ),
            )
        )
    );
    return widgets;
  }
  Widget _playerNameWidget(player){
    if(this._is_full && !this.selectedPlayers.contains(player)){ //show disabled selection
      return Opacity(opacity:.25, child:Text("${player.playerName}"));
    }
    else {
      if(this.widget.league.hasBudget){ // can afford player, not full
        if(player.playerPrice <= widget.remaining || this.selectedPlayers.contains(player)){
          return Text("${player.playerName}");
        }
        else { // can't afford player, not full
          return Opacity(opacity:.25, child:Text("${player.playerName}"));
        }
      }
      else { // slot still open
        return Text("${player.playerName}");
      }
    }
  }
  Widget _playerPicWidget(player){
    if(player == this.draftedPlayer){
      return Opacity(opacity: .25, child: Image.network('${player.playerImageUrl}',
      fit: BoxFit.scaleDown,
      height: 45,
      width: 45,
      ));
    }
    else {
        if(player.playerPrice <= widget.remaining || this.selectedPlayers.contains(player)){
          return Image.network('${player.playerImageUrl}',
            fit: BoxFit.scaleDown,
            height: 45,
            width: 45,
          );
        }
    }
  }
  Widget _trailingWidget(player){
    List<Widget> tWidgets;
    double playerOpacity = 1;
    if(player.playerPrice > widget.remaining){
      playerOpacity = .25;
    }
    tWidgets = [
      Padding(padding: const EdgeInsets.symmetric(horizontal:10.0),
      child: Opacity(opacity:playerOpacity, child:Text("\$${globals.commaFormat.format(player.playerPrice)}")),
    ), Opacity(opacity: playerOpacity, child: Icon(Icons.add))];
    return Row(mainAxisSize: MainAxisSize.min, children: tWidgets);
  }
}

1 个答案:

答案 0 :(得分:0)

问题是与数据传递无关的数据问题。