How To Create A Table Of Buttons In Flutter And Randomly Select Any Button From It?
Solution 1:
Now I want to select some random buttons from the table and set an onPressed function on them. How can I proceed?
The safest place to store the button's "identity" be it first or 10th or 100th button is inside it.
classGameButtonextendsStatelessWidget {
finalint 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:
classGameButtonextendsStatelessWidget {
finalint id;
finalFunction(int) onPressed;
const GameButton({
this.id,
this.onPressed,
})
...
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:
classGameButtonextendsStatelessWidget {
finalint id;
finalFunction(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,
);
}
}
We'll define what to do with this id
when creating each button:
...
new GameButton(
id: id,
onPressed: onButtonClicked,
),
...
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 idint id = 0;
for (var i = 0; i < widget.rows; i++) {
// new empty row
List<Widget> rowChildren = [];
// ---------------------- id incremented herefor (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;
}
And here is the handler:
onButtonClicked(intid) {
// this id ^ variable is the one coming fromany clicked button
// use it e.g. to compare withany other variables from State
print("clicked button $id");
}
This is the code to get random number:
intmax = widget.rows * widget.cols - 1;
this.randomSelection =
Random.secure().nextInt(max);
Final result might look like :
import'package:flutter/material.dart';
import'dart:math';
classButtonTableextendsStatefulWidget{
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_ButtonTableStateextendsState<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);
}
}
classGameButtonextendsStatelessWidget{
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 = whiteif (!this.playing)
return Colors.white;
elseif (this.crossed) {
return Colors.yellow;
}
}
decideText() {
return Text(
playing ? "$id" : '',
style: TextStyle(
color: crossed ? Colors.green : Colors.black,
fontWeight: crossed ? FontWeight.bold : FontWeight.normal,
),
);
}
}
Have fun
Solution 2:
I don't get your question clearly, Can you explain it more ? but you can change buttons color like this.
declare a variable :
bool didColourChange = false;
FlatButton(color:didColourChange?Colors.red:Colors.green,onPressed:() {
setState(() {
didColourChange=!didColourChange;
});
},)
Solution 3:
If you wanted to add some animations, you can use AnimatedContainer widget together with GestureDetector instead of using FlatButton
widget.
To avoid hard coding your children
, you might want to use the map method of List class but that's only applicable if you're storing your numbers inside a list.
Here's the output:
Here's the full code:
import'package:flutter/material.dart';
voidmain() => runApp(MyApp());
classMyAppextendsStatelessWidget {
@overrideWidgetbuild(BuildContext context) {
returnMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
classMyHomePageextendsStatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class_MyHomePageStateextendsState<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,
);
@overrideWidgetbuild(BuildContext context) {
returnScaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: newContainer(
child: newTable(
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: constDuration(milliseconds: 700),
height: 56.0,
color: pressedValues[val] ? Colors.red : Colors.green,
child: Center(
child: pressedValues[val] ? Text(val.toString()) : Text(""),
)
)
)
).toList()
)
).toList()
)
)
);
}
}
Post a Comment for "How To Create A Table Of Buttons In Flutter And Randomly Select Any Button From It?"