如何在Flutter中创建按钮表并从中随机选择任何按钮? [英] How to create a Table of buttons in Flutter and randomly select any button from it?

查看:75
本文介绍了如何在Flutter中创建按钮表并从中随机选择任何按钮?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆