Home > Blockchain >  Error during flutter null safety migration : type 'Null' is not a subtype of type 'Cp
Error during flutter null safety migration : type 'Null' is not a subtype of type 'Cp

Time:06-21

Hello I upgrade my old working code to the last flutter null safety, but now I have this error when I press my RawMaterialButton.

 type 'Null' is not a subtype of type 'Cpu'

     new RawMaterialButton(
                  onPressed: () {
                    Navigator.pushNamed(
                      context,
                      '/match',
                      arguments: {
                        'mode': Mode.PVC,
                        'cpu': DumbCpu(
                            Random().nextBool() ? Player.RED : Player.YELLOW),
                      },
                    );
                  },
                  child: Text("Faible",style: TextStyle(
                      color: Colors.black,
                      fontWeight: FontWeight.w600,
                      fontSize: SizeConfig.safeBlockHorizontal! * 5),
                  ),
                  shape: new CircleBorder(),
                  elevation: 2.0,
                  fillColor: Colors.white,
                  padding: const EdgeInsets.all(40.0),
                ),



    class Home extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: '',
    
          home: HomePage(),
          onGenerateRoute: (settings) {
            final args = settings.arguments as Map<String, dynamic>;
            if (settings.name == '/match') {
              return MaterialPageRoute(
                builder: (context) => MatchPage(
                  mode: args['mode'],
                  cpu: args['cpu'],
                  cpu2: args['cpu2'],
                ),
              );
            } else if (settings.name == '/cpu-level') {
              return MaterialPageRoute(
                builder: (context) => CpuLevelPage(),
              );
            }
    
            return null;
          },
        );
      }
    }

-----------------------------------------------

class MatchPage extends StatefulWidget {
  final Mode mode;
  final Cpu cpu;
  final Cpu cpu2;

  const MatchPage({
    Key? key,
   required  this.mode,
    required this.cpu,
    required this.cpu2,
  }) : super(key: key);

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

class _MatchPageState extends State<MatchPage> with TickerProviderStateMixin {
  final board = Board();
  late Player turn;
  late   Player winner;

  List<List<Animation<double>?>> translations = List.generate(
    7,
        (i) => List.generate(
      7,
          (i) => null,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor:  Color(0xff61d3cb),
      appBar: AppBar(
   
          title: Text('Que le meilleur gagne '),
          backgroundColor:   Color(0xff61d3cb),

          leading: IconButton(icon:Icon(Icons.arrow_back),
              onPressed: () {

                Navigator.pushAndRemoveUntil(context,   MaterialPageRoute(
                  builder: (context) => home(),
                ), (e) => false);
   
              }
          )

      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(

          children: <Widget>[
            Flexible(
              flex: 2,
              child: Padding(
                padding: const EdgeInsets.only(top: 1.0),
                child: Stack(
                  children: <Widget>[
                    Positioned.fill(
                      child: Container(
                        color: Colors.white,
                      ),
                    ),
                    buildPieces(),
                    buildBoard(),
                  ],
                ),
              ),
            ),
            Flexible(
              flex: 1,
              child: Padding(
                padding: const EdgeInsets.all(10.0),
                child: winner != null
                    ? Text(
                  'Les ${winner == Player.RED ? 'Rouges' : 'Jaunes'} Gagnent',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                      color: Colors.black,
                      fontWeight: FontWeight.w600,
                      fontSize: SizeConfig.safeBlockHorizontal! * 7),

                )
                    : ListView(
                  children: <Widget>[
                    Text(
                      'Au tour des ${turn == Player.RED ? 'Rouges' : 'Jaunes'} ',
                      textAlign: TextAlign.center,
                      style: TextStyle(
                          color: Colors.white,
                          fontWeight: FontWeight.w600,
                          fontSize: SizeConfig.safeBlockHorizontal! * 6),

                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: GameChip(color: turn),
                    ),
                    _buildPlayerName(context),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Text _buildPlayerName(BuildContext context) {
    String name;

    if (widget.mode == Mode.PVC) {
      if (turn == widget.cpu.player) {
        name = 'Ordinateur';
      } else {
        name = 'Toi';
      }
    } else if (widget.mode == Mode.PVP) {
      if (turn == Player.RED) {
        name = 'Joueur1';
      } else {
        name = 'Joueur2';
      }
    } else {
      if (turn == widget.cpu.player) {
        name = 'Ordinateur';
      } else {
        name = 'Ordinateur';
      }
    }
    return Text(
      name,
      textAlign: TextAlign.center,
      style: TextStyle(
          color: Colors.white,
          fontWeight: FontWeight.w600,
          fontSize: SizeConfig.safeBlockHorizontal! * 6),


    );
  }

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

    if (widget.mode == Mode.PVC && turn == widget.cpu.player) {
      cpuMove(widget.cpu);
    } else if (widget.mode == Mode.DEMO) {
      if (turn == widget.cpu.player) {
        cpuMove(widget.cpu);
      } else {
        cpuMove(widget.cpu2);
      }
    }
  }

  GridView buildPieces() {
    return GridView.custom(
      padding: const EdgeInsets.all(0),
      shrinkWrap: true,
      physics: NeverScrollableScrollPhysics(),
      gridDelegate:
      SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 7),
      childrenDelegate: SliverChildBuilderDelegate(
            (context, i) {
          final col = i % 7;
          final row = i ~/ 7;

          if (board.getBox(Coordinate(col, row)) == null) {
            return SizedBox();
          }

          return GameChip(
            translation: translations[col][row],
            color: board.getBox(Coordinate(col, row)),
          );
        },
        childCount: 49,
      ),
    );
  }

  GridView buildBoard() {
    return GridView.custom(
      padding: const EdgeInsets.all(0),
      physics: NeverScrollableScrollPhysics(),
      gridDelegate:
      SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 7),
      shrinkWrap: true,
      childrenDelegate: SliverChildBuilderDelegate(
            (context, i) {
          final col = i % 7;

          return GestureDetector(
            onTap: () {
              if (winner == null) {
                userMove(col);
              }
            },
            child: CustomPaint(
              size: Size(50, 50),
              willChange: false,
              painter: HolePainter(),
            ),
          );
        },
        childCount: 49,
      ),
    );
  }

  void userMove(int col) {
    putChip(col);
    if (winner == null && widget.mode == Mode.PVC) {
      cpuMove(widget.cpu);
    }
  }

  void cpuMove(Cpu cpu) async {
    int col = await cpu.chooseCol(board);
    putChip(col);

    if (winner == null && widget.mode == Mode.DEMO) {
      if (turn == widget.cpu.player) {
        cpuMove(widget.cpu);
      } else {
        cpuMove(widget.cpu2);
      }
    }
  }

  void putChip(int col) {
    final target = board.getColumnTarget(col);
    final player = turn;

    if (target == -1) {
      return;
    }

    final controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 1),
    )..addListener(() {
      if (mounted) {
        setState(() {});
      }
    });

    if (mounted) {
      setState(() {
        board.setBox(Coordinate(col, target), turn);
        turn = turn == Player.RED ? Player.YELLOW : Player.RED;
      });
    }

    translations[col][target] = Tween(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      curve: Curves.bounceOut,
      parent: controller,
    ))
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          controller.dispose();
        }
      });

    controller.forward().orCancel;

    if (board.checkWinner(Coordinate(col, target), player)) {
      showWinnerDialog(context, player);
    }
  }

  void showWinnerDialog(BuildContext context, Player player) {
    setState(() {
      winner = player;
    });

    Future.delayed(
      Duration(seconds: 5),
          () => mounted ? Navigator.popUntil(context, (r) => r.isFirst) : null,
    );
  }

  void resetBoard() {
    setState(() {
    //  winner = null;
      board.reset();
    });
  }
}

CodePudding user response:

Allow null for cpu2 or pass it for '/match' route.

MatchPage(
  mode: args['mode'],
  cpu: args['cpu'],
  cpu2: args['cpu2'],
),
``

CodePudding user response:

I think you are passing the data

arguments: {
                    'mode': Mode.PVC,
                    'cpu': DumbCpu(
                        Random().nextBool() ? Player.RED : Player.YELLOW),
                  },

but you are trying to access

return MaterialPageRoute(
            builder: (context) => MatchPage(
              mode: args['mode'],
              cpu: args['cpu'],
              cpu2: args['cpu2'], /// args['cpu2'] is not passed but you are accenting it.
            ),
          );

So I think fixing this will resolve your issue. I'll be looking forward to resolve your query :)

  • Related