Magic-8-Ball был выбран в качестве первой истории серии Flutter, потому что предыдущие задания/проекты были немного недостаточны с точки зрения предоставления большого количества полезных деталей. Итак, давайте посмотрим на исходный код.
import 'package:flutter/material.dart'; import 'dart:math'; void main() => runApp( MaterialApp( home: BallPage(), ), ); class BallPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.blue[900], title: Text("Ask Me Anything"), ), body: Ball(), backgroundColor: Colors.blue, ); } } class Ball extends StatefulWidget { @override _BallState createState() => _BallState(); } class _BallState extends State<Ball> { int ballNumber = 1; @override Widget build(BuildContext context) { return Center( child: FlatButton( onPressed: () { setState(() { ballNumber = Random().nextInt(4) + 1; }); }, child: Image.asset("images/ball$ballNumber.png"), ), ); } }
Шаг 1 — Настройка
Сначала я скачал скелет проекта из репозитория git appbrewery. Скелетный код выглядит так:
import 'package:flutter/material.dart'; void main() => runApp( MaterialApp( home: null, ), );
Там почти ничего нет, кроме MaterialApp, который является основой практически для всего. MaterialApps — важная основа, потому что именно их задумал разработчик Google, чтобы дать нам своего рода блокнот для разработки приложений.
Шаг 2 — Создайте виджет без сохранения состояния
Это легко. Все, что мне нужно было сделать, это ввести «stless» где-нибудь в файле main.dart и автозаполнить остальную часть кода виджета без сохранения состояния. Виджет без сохранения состояния назывался BallPage. Затем в MaterialApp вы можете увидеть, что свойство «home» имеет значение «null». Я изменил это нулевое значение на BallPage, чтобы этот виджет без сохранения состояния теперь стал домом для этого MaterialApp.
Следующая часть этого шага — некоторые раскраски. Давайте взглянем на готовую часть кода виджета без сохранения состояния.
class BallPage extends StatelessWidget { @override Widget build(BuildContext context) { return Container(); } }
Вы можете видеть, что внутри метода сборки он возвращает только контейнер. Давайте исправим это и добавим AppBar (у которого есть backgroundColor и заголовок) и body (у которого пока есть Container) и свой собственный backgroundColor.
class BallPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.blue[900], title: Text("Ask Me Anything"), ), body: Container(), backgroundColor: Colors.blue, ); } }
Вот диаграмма.
Крутая вещь. Идем дальше.
Шаг 3 — Создайте виджет с отслеживанием состояния
Точно так же, как я создал файл без гражданства, я использовал для этого ярлык «stful». Взгляните на автозаполнение по умолчанию.
class Ball extends StatefulWidget { @override _State createState() => _State(); } class _State extends State<> { @override Widget build(BuildContext context) { return Container(); } }
Помните Контейнер для тела виджета без сохранения состояния? Пришло время изменить это.
class BallPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.blue[900], title: Text("Ask Me Anything"), ), body: Ball(), backgroundColor: Colors.blue, ); } }
Теперь BallPage будет иметь виджет с состоянием Ball в качестве тела. Давайте перейдем к виджету Ball с состоянием, сделаем его центрированным и добавим FlatButton. Давайте также сделаем эту FlatButton изображением шара-восьмерки.
class Ball extends StatefulWidget { @override _BallState createState() => _BallState(); } class _BallState extends State<Ball> { int ballNumber = 1; @override Widget build(BuildContext context) { return Center( child: FlatButton( child: Image.asset("images/ball1.png"), ), ); } }
Шаг 4 — Сделайте его интерактивным
Внутри FlatButton вам нужно «onPressed: () {}», внутри которого также должно быть что-то, что изменяет какое-то состояние… что-то вроде «setState (() {});»
class _BallState extends State<Ball> { @override Widget build(BuildContext context) { return Center( child: FlatButton( onPressed: () { setState(() { }); }, child: Image.asset("images/ball1.png"), ), ); } }
Шаг 5 — Рандомизируйте это
Пришло время импортировать математическую библиотеку.
import 'dart:math';
Тогда используйте его. Перед реализацией этого генератора случайных чисел создайте переменную, чтобы применить это случайное число к пути к файлу. Давайте назовем его «ballNumber» и поместим вне метода сборки, чтобы переменная не генерировалась каждый раз при вызове метода сборки.
class Ball extends StatefulWidget { @override _BallState createState() => _BallState(); } class _BallState extends State<Ball> { int ballNumber = 1; @override Widget build(BuildContext context) { return Center( child: FlatButton( onPressed: () { setState(() { ballNumber = Random().nextInt(4) + 1; }); }, child: Image.asset("images/ball$ballNumber.png"), ), ); } }
Это оно! Проект завершен.