如何在Flutter中创建按钮表并从中随机选择任何按钮? [英] How to create a Table of buttons in Flutter and randomly select any button from it?
问题描述
我试图在Flutter中创建一个自定义的Housie Game Ticket Generator,在其中我必须从4X3的按钮表中随机选择一个按钮,并显示否。在该按钮上。点击按钮后,它的颜色从绿色变为红色。
I am trying to create a custom Housie Game Ticket Generator in Flutter, in which I have to randomly select a button from a 4X3 table of buttons, and show a no. on that button. On clicking the button, it changes it's colour from Green to Red.
我通过对所有单元格进行硬编码,创建了一个4X3的按钮表,如下所示。现在,我想从表中选择一些随机按钮,并在其上设置onPressed函数。我该如何进行?
I have created a 4X3 table of buttons by hard coding all the cells as seen below. Now I want to select some random buttons from the table and set an onPressed function on them. How can I proceed?
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: () {},
)
]
),
]
),
)
推荐答案
现在,我想从表中选择一些随机按钮,并在其上设置
onPressed函数。我该如何进行?
Now I want to select some random buttons from the table and set an onPressed function on them. How can I proceed?
最安全的位置是存储按钮的身份,无论它位于按钮的第一个,第10个还是第100个。
The safest place to store the button's "identity" be it first or 10th or 100th button is inside it.
class GameButton extends StatelessWidget {
final int id;
const GameButton({
this.id,
})
...
单击按钮时,您希望在单击的那一刻获得该信息-让按钮使我们告诉此信息:
When the button is clicked , you want that info in the very moment of the click - let's make button tell us this info:
class GameButton extends StatelessWidget {
final int id;
final Function(int) onPressed;
const GameButton({
this.id,
this.onPressed,
})
...
请注意此处添加的 Function(int)onPressed
-这是一个回调,它传递了整数,我们将在单击按钮时调用它,并让按钮将 id
传递给此函数:
Mind the Function(int) onPressed
added here - it's a callback which passes out an integer, we'll call it when the button is clicked and let the button pass it's id
to this function:
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,
);
}
}
我们将定义对此 id
创建每个按钮时:
We'll define what to do with this id
when creating each button:
...
new GameButton(
id: id,
onPressed: onButtonClicked,
),
...
要创建按钮表,您可以首先将它们写入 List< TableRow>
,在每一行中填充所需数量的按钮,然后进行设置整个行列表,作为儿童
到表
:
To create table of buttons you can first write them to List<TableRow>
, fill each row with desired number of buttons, and then set the whole list of rows as children
to Table
:
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;
}
这是处理程序:
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");
}
这是获取随机数的代码:
This is the code to get random number:
int max = widget.rows * widget.cols - 1;
this.randomSelection =
Random.secure().nextInt(max);
最终结果可能类似于:
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,
),
);
}
}
玩得开心
这篇关于如何在Flutter中创建按钮表并从中随机选择任何按钮?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!