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 :)