在设置状态内更新变量

时间:2019-08-05 20:30:05

标签: flutter setstate

我对颤振还很陌生,我有一个颜色列表,我希望能够触摸一个容器并在列表中的不同颜色之间切换。这将更新容器的颜色。同样,在这种情况2下,我可以有多个容器,因此触摸一个容器不应更新其他容器。

我让它使用一个容器工作,但是在创建了一种返回小部件的方法之后,我可以有多个容器,但这是行不通的。

 import 'package:flutter/material.dart';

class NewGame extends StatefulWidget {
  final Color team1;
  final Color team2;
  final Color team3;

  NewGame(this.team1, this.team2, this.team3);

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

class _NewGameState extends State<NewGame> {
  List<Color> teamColors;
  int team1Index = 0;
  int team2Index = 0;

  @override
  void initState() {
    super.initState();
    teamColors = [widget.team1, widget.team2, widget.team3];
  }

  Widget _buildTeamSelector(int teamIndex) {   
    return GestureDetector(
                onTap: () {
                  setState(() {
                    print('Value of teamColorIndex ${teamIndex.toString()}');
                    if (teamIndex < teamColors.length - 1) {
                      teamIndex++;
                    } else {
                      teamIndex = 0;
                    }
                  });
                },
                child: Container(
                  height: 75,
                  width: 75,
                  decoration: BoxDecoration(
                    color: teamColors[teamIndex],
                    borderRadius: BorderRadius.circular(50),
                  ),
                ),
              );
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 5,
      child: Column(
        children: <Widget>[
          Column(
            children: <Widget>[
              Text('Value of team1Index: :$team1Index'),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text('Teams:'),
                  _buildTeamSelector(team1Index),
                  _buildTeamSelector(team2Index),
                  Text('Red'),
                ],
              ),
            ],
          ),
        ],
      ),
    );
  }
}

I/flutter (12114): Value of teamColorIndex 0
I/chatty  (12114): uid=10085(com.example.game_tracker) Thread-2 identical 1 line
I/flutter (12114): Value of teamColorIndex 0
I/flutter (12114): Value of teamColorIndex 0
I/chatty  (12114): uid=10085(com.example.game_tracker) Thread-2 identical 4 lines
I/flutter (12114): Value of teamColorIndex 0
I/flutter (12114): Value of teamColorIndex 0

在setState中,变量似乎没有更新。我知道这是问题,但我不知道为什么。

2 个答案:

答案 0 :(得分:2)

您要更新的变量不是您认为的变量。

您有两个同名变量:

  • State的属性
  • 参数_buildTeamSelector

您在setState调用中所做的更改不是State属性,而是方法的参数。

代替:

int a;
void foo(int a) {
  a++;
}

这样做:

int a;
void foo(int a) {
  this.a++; //properly update the instance member instead of the parameter
}

答案 1 :(得分:1)

您尝试更新值传递的参数。 Dart不支持通过引用传递原始类型,因此您需要将原始值包装在这样的对象中:

class Team {
  int index;

  Team(this.index);
}

class NewGame extends StatefulWidget {
  final Color team1;
  final Color team2;
  final Color team3;

  NewGame(this.team1, this.team2, this.team3);

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

class _NewGameState extends State<NewGame> {
  List<Color> teamColors;
  var team1 = Team(0);
  var team2 = Team(0);

  @override
  void initState() {
    super.initState();
    teamColors = [widget.team1, widget.team2, widget.team3];
  }

  Widget _buildTeamSelector(Team team) {
    return GestureDetector(
      onTap: () {
        setState(() {
          print('Value of teamColorIndex ${team.index.toString()}');
          if (team.index < teamColors.length - 1) {
            team.index++;
          } else {
            team.index = 0;
          }
        });
      },
      child: Container(
        height: 75,
        width: 75,
        decoration: BoxDecoration(
          color: teamColors[team.index],
          borderRadius: BorderRadius.circular(50),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 5,
      child: Column(
        children: <Widget>[
          Column(
            children: <Widget>[
              Text('Value of team1.index: :${team1.index}'),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text('Teams:'),
                  _buildTeamSelector(team1),
                  _buildTeamSelector(team2),
                  Text('Red'),
                ],
              ),
            ],
          ),
        ],
      ),
    );
  }
}