iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
0
Mobile Development

30天手滑用Google Flutter解鎖Hybrid App成就系列 第 16

30天Flutter手滑系列 - 井字遊戲實作(Tic Tac Toe)(3)

前一天的文章30天Flutter手滑系列 - 井字遊戲實作(Tic Tac Toe)(2),我們停在點擊按鈕後控制OX的部分,今天我們來完成它。

預期做法

為了達到點擊按鈕,然後更新按鈕文字的目的,我們需要用到之前文章提到的狀態管理方式,透過setState的方式,讓flutter知道Widget的狀態已經改變,才能即時更新我們需要的內容。

定義抽象類別

首先,我們先定義一個類別,簡單包含idtextenabled這三個屬性,方便記錄之後每個按鈕的變化。

class GameButton {
  final id;
  String text;
  bool enabled;

  GameButton({this.id, this.text = "", this.enabled = false});
}

初始化按鈕列表

為了讓每個按鈕有對應的狀態,我們先宣告一個內容為GameButtonList變數gameButtons

List<GameButton> gameButtons;

透過initState,初始化整個gameButtons的狀態。因為有9個按鈕,這裡我們需要new 9個GameButton

void initState() {
    gameButtons = <GameButton>[
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
    ];
  }

狀態更新

如前面文章提到,狀態的改變可以透過setState()這個方法,因此我們加入一個_playGame的函數,並傳入index當參數,讓按鈕點擊時可以去呼叫這個函數,去進行資料更新的動作。

void _playGame(index) {
    setState(() {
      gameButtons[index].enabled = true;
    });
  }

綁定函數

定義好上述變數與函數後,就是把這些與Button的onPressed做連結。

onPressed: () {
    _playGame(index); // 這邊的index,來自於List.generate(9, index)
}

而顯示X的文字部分,我們可以加入判斷如下。

child: Text(
   gameButtons[index].enabled ? "X" : "",
   style: TextStyle(fontSize: 50.0),
)

如此一來,我們就可以根據點擊到的按鈕,再改變其狀態填入文字了。

https://upload.cc/i1/2019/09/23/peMfAa.gif

完整程式碼

class GameButton {
  final id;
  String text;
  bool enabled;

  GameButton({this.id, this.text = "", this.enabled = false});
}

class _TicTacToePageState extends State<TicTacToePage> {
  List<GameButton> gameButtons;

  void initState() {
    gameButtons = <GameButton>[
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
      new GameButton(),
    ];
  }

  void _playGame(index) {
    setState(() {
      gameButtons[index].enabled = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          GridView.count(
              crossAxisCount: 3,
              shrinkWrap: true,
              children: List.generate(9, (index) {
                return Container(
                  padding: EdgeInsets.all(8.0),
                  child: FlatButton(
                    child: Text(
                      gameButtons[index].enabled ? "X" : "",
                      style: TextStyle(fontSize: 50.0),
                    ),
                    color: Colors.grey,
                    textColor: Colors.white,
                    onPressed: () {
                      _playGame(index);
                    },
                  ),
                );
              })),
          Center(
            child: ButtonTheme(
              minWidth: 200,
              height: 80,
              child: RaisedButton(
                color: Colors.blue,
                child: Text('Start Game'),
                onPressed: null,
              ),
            ),
          )
        ],
      ),
    );
  }
}


上一篇
30天Flutter手滑系列 - 井字遊戲實作(Tic Tac Toe)(2)
下一篇
30天Flutter手滑系列 - 井字遊戲實作(Tic Tac Toe)(4)
系列文
30天手滑用Google Flutter解鎖Hybrid App成就30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言