J'essaie de créer un générateur de tickets de jeu Housie personnalisé dans Flutter, dans lequel je dois sélectionner au hasard un bouton dans une table de boutons 4X3 et afficher un non. sur ce bouton. En cliquant sur le bouton, sa couleur passe du vert au rouge.
J'ai créé un tableau 4X3 de boutons en codant en dur toutes les cellules comme indiqué ci-dessous. Maintenant, je veux sélectionner des boutons aléatoires dans le tableau et définir une fonction onPressed sur eux. Comment puis-je procéder?
body: new Container(
child: new Table(
border: TableBorder.all(),
children: [
TableRow(
children: [
new FlatButton(
color: Colors.white,
onPressed: () {},
),
new FlatButton(
color: Colors.white,
onPressed: () {},
),
new FlatButton(
color: Colors.white,
onPressed: () {},
),
new FlatButton(
color: Colors.white,
onPressed: () {},
)
]
),
TableRow(
children: [
new FlatButton(
color: Colors.white,
onPressed: () {},
),
new FlatButton(
color: Colors.white,
onPressed: () {},
),
new FlatButton(
color: Colors.white,
onPressed: () {},
),
new FlatButton(
color: Colors.white,
onPressed: () {},
)
]
),
TableRow(
children: [
new FlatButton(
color: Colors.white,
onPressed: () {},
),
new FlatButton(
color: Colors.white,
onPressed: () {},
),
new FlatButton(
color: Colors.white,
onPressed: () {},
),
new FlatButton(
color: Colors.white,
onPressed: () {},
)
]
),
]
),
)
3 Réponses :
Je ne comprends pas clairement votre question. Pouvez-vous l'expliquer davantage? mais vous pouvez changer la couleur des boutons comme ceci.
déclarer une variable:
bool didColourChange = false;
FlatButton(
color: didColourChange ? Colors.red: Colors.green,
onPressed: () {
setState(() {
didColourChange = !didColourChange;
});
},
)
Maintenant, je veux sélectionner des boutons aléatoires dans le tableau et définir un Fonction onPressed sur eux. Comment puis-je procéder?
L'endroit le plus sûr pour stocker «l'identité» du bouton, que ce soit le premier, le 10e ou le 100e bouton, se trouve à l'intérieur.
import 'package:flutter/material.dart'; import 'dart:math'; class ButtonTable extends StatefulWidget { final int rows; final int cols; const ButtonTable({Key key, this.rows: 6, this.cols: 4}) : super(key: key); get max => rows * cols - 1; @override _ButtonTableState createState() => _ButtonTableState(); } class _ButtonTableState extends State<ButtonTable> { int randomNumber = -1; List<int> pot; List<int> crossedNumbers; List<int> initialTicket; String resultText = ""; String statusText = "Roll it"; @override void initState() { super.initState(); restart(); } void restart() { initialTicket = generateTicket(); pot = List.generate(widget.max, (index) => index); crossedNumbers = []; randomNumber = -1; } List<int> generateTicket() { var temp = List.generate(widget.max, (index) => index); List<int> ticket = []; for (int i = 0; i < widget.max / 2; i++) { final randomIndex = Random.secure().nextInt(temp.length); ticket.add(temp.removeAt(randomIndex)); } return ticket; } @override Widget build(BuildContext context) { return Container( child: Column( children: <Widget>[ new Table( border: TableBorder.all(), children: buildButtons(), ), Text("$statusText"), Text("$resultText"), Center( child: Row( children: <Widget>[ FlatButton( color: Colors.grey, onPressed: rollNext, child: Text("Roll"), ), FlatButton( color: Colors.grey, onPressed: () { setState(() { restart(); }); }, child: Text("Restart")), ], ), ), Text("Pot:" + pot.toString()) ], )); } onButtonClicked(id) { setState(() { if (id == randomNumber) { if (isNumberPlaying(id)) { resultText = Random.secure().nextBool() ? "Housie" : "Whoo"; statusText = "Pull next number"; crossedNumbers.add(id); } else { resultText = Random.secure().nextBool() ? "You can't cheat machine code" : "Nice try, but you don't have it on your ticket!"; } } else { resultText = Random.secure().nextBool() ? "Missed, are u ok?" : "Try harder"; } }); } List<TableRow> buildButtons() { List<TableRow> rows = []; int id = 0; for (var i = 0; i < widget.rows; i++) { // new empty row List<Widget> rowChildren = []; for (var y = 0; y < widget.cols; y++, id++) { // fill row with buttons rowChildren.add( new GameButton( id: id, playing: isNumberPlaying(id), crossed: isCrossed(id), onPressed: onButtonClicked, ), ); } rows.add(new TableRow(children: rowChildren)); } return rows; } rollNext() { setState(() { if (pot.length > 0) { int randomIndex = Random.secure().nextInt(pot.length); this.randomNumber = pot.removeAt(randomIndex); this.statusText = "Rolled: $randomNumber"; this.resultText = "playing one more time..."; } else { restart(); } }); } isNumberPlaying(int id) { return initialTicket.contains(id); } isCrossed(int id) { return crossedNumbers.contains(id); } } class GameButton extends StatelessWidget { final int id; final Function(int) onPressed; final bool playing; final bool crossed; const GameButton({ Key key, this.id, this.onPressed, this.playing, this.crossed, }) : super(key: key); @override Widget build(BuildContext context) { return FlatButton( color: decideColor(), onPressed: () { onPressed(this.id); }, child: Stack( children: <Widget>[ Visibility( visible: crossed, child: Icon( Icons.done, size: 48, color: Colors.brown, )), decideText() ], ), ); } Color decideColor() { // if id is not active = white if (!this.playing) return Colors.white; else if (this.crossed) { return Colors.yellow; } } decideText() { return Text( playing ? "$id" : '', style: TextStyle( color: crossed ? Colors.green : Colors.black, fontWeight: crossed ? FontWeight.bold : FontWeight.normal, ), ); } }Lorsque vous cliquez sur le bouton, vous voulez cette information au moment même du clic - faisons en sorte que le bouton nous dise cette info:
int max = widget.rows * widget.cols - 1; this.randomSelection = Random.secure().nextInt(max);Attention à la
Function (int) onPressedajoutée ici - c'est un callback qui passe un entier, nous l'appellerons quand le bouton sera cliqué et laisserons le bouton passer sonidà cette fonction:onButtonClicked(int id) { // this id ^ variable is the one coming from any clicked button // use it e.g. to compare with any other variables from State print("clicked button $id"); }Nous définirons quoi faire avec cet
idlors de la création de chaque bouton:List<TableRow> buildButtons() { // list for all rows List<TableRow> rows = []; // each button get's unique id int id = 0; for (var i = 0; i < widget.rows; i++) { // new empty row List<Widget> rowChildren = []; // ---------------------- id incremented here for (var y = 0; y < widget.cols; y++,id++) { // fill row with buttons rowChildren.add( new GameButton( id: id, onPressed: onButtonClicked, ), ); } rows.add(new TableRow(children: rowChildren)); } return rows; }Pour créer un tableau de boutons, vous pouvez d'abord les écrire dans
Listez, remplissez chaque ligne avec le nombre de boutons souhaité, puis définissez la liste complète des lignes commeenfantssurTable:... new GameButton( id: id, onPressed: onButtonClicked, ), ...Et voici le gestionnaire:
class GameButton extends StatelessWidget { final int id; final Function(int) onPressed; const GameButton({this.id, this.onPressed}); @override Widget build(BuildContext context) { return FlatButton( onPressed: () { // on click, we pass id to onPressed(int) onPressed(this.id); }, child: null, ); } }Voici le code pour obtenir un nombre aléatoire:
class GameButton extends StatelessWidget { final int id; final Function(int) onPressed; const GameButton({ this.id, this.onPressed, }) ...
Si vous souhaitez ajouter des animations, vous pouvez utiliser AnimatedContainer a > widget avec GestureDetector au lieu d'utiliser Pour éviter de coder en dur vos Voici le résultat: Voici le code complet: FlatButton code> widget. enfants , vous pouvez utiliser le map méthode de List , mais cela ne s'applique que si vous stockez vos numéros dans une liste. import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<List<int>> someListsOfNumbers = [
List.generate(4, (int idx) => idx),
List.generate(4, (int idx) => idx + 4),
List.generate(4, (int idx) => idx + 8),
];
Map<int, bool> pressedValues = Map.fromIterable(
List.generate(12, (int idx) => idx),
key: (item) => item,
value: (item) => false,
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: new Container(
child: new Table(
border: TableBorder.all(),
children: someListsOfNumbers.map(
(List<int> someList) => TableRow(
children: someList.map((int val) => GestureDetector(
onTap: (){
setState((){
pressedValues[val] = !pressedValues[val];
});
},
child: AnimatedContainer(
duration: const Duration(milliseconds: 700),
height: 56.0,
color: pressedValues[val] ? Colors.red : Colors.green,
child: Center(
child: pressedValues[val] ? Text(val.toString()) : Text(""),
)
)
)
).toList()
)
).toList()
)
)
);
}
}