DevGang
Авторизоваться

Изучите Flutter, создав свое первое приложение Flutter!

В этой статье я собираюсь познакомить вас с вашим первым приложением Flutter. Мы рассмотрим части проекта Flutter, их роли и рассмотрим некоторые фундаментальные концепции состояния, включая различия между StatelessWidgets и StatefulWidgets.

Если вы еще не установили Flutter, вот несколько пошаговых видеороликов, которые проведут вас через процесс установки Flutter на Mac, Windows и Linux.

📽 Видеоверсия доступна на YouTube

Создание базового приложения Flutter

Начнем с создания базового приложения. Вы можете сделать это из меню вашего любимого редактора кода, хотя я всегда предпочитаю делать это из терминала:

flutter create flutter_test_app

Эта команда создаст базовое приложение для подсчета, которое при выполнении позволит нам увеличивать числовое значение, нажав кнопку:

Цель этого примера кода — дать вам первое представление о Flutter. Мы будем постепенно идти к пониманию этого шаблона, который нам уже дан.

Файл конфигурации pubspec.yaml

Первое, что мы собираемся рассмотреть, это файл pubspec.yaml:

Этот файл содержит основные метаданные приложения, перечисляет все зависимости и включает различные параметры конфигурации. Если вы откроете его, вы найдете комментарии к каждому разделу, объясняющие их назначение. Однако для ясности мы удалим эти комментарии, чтобы файл был простым и кратким обзором каждого сегмента:

name: flutter_test_app
description: "You can add a description for your project here."
publish_to: 'none'
version: 1.0.0+1

environment:
   sdk: '>=3.2.6 <4.0.0'

Разъясним значение каждого параметра:

  • Name: представляет имя проекта. Оно служит «внутренним» идентификатором и не является именем, предоставляемым вашим пользователям.
  • Описание: это поле позволяет вам предоставить краткое описание цели вашего проекта.
  • Publish_to: этот параметр в первую очередь актуален для разработки пакетов. Поскольку эта статья посвящена базовым понятиям, мы оставим ее без изменений.
  • Версия: Здесь вы можете указать версию вашего проекта, используя семантическое управление версиями, за которым следует дополнительное целое число. Такая практика позволяет осуществлять контроль версий непосредственно из этого файла, который затем применяется ко всем проектам, специфичным для платформы. Завершающее целое число обычно соответствует коду версии в проектах Android.
  • Среда: здесь указывается совместимый диапазон версий Dart SDK для вашего приложения. Если в будущем вы захотите использовать новые версии Dart SDK, возможно, вам будет интересно изменить его, но сейчас мы оставляем все как есть.
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0

Следующая часть посвящена зависимостям приложения, которые делятся на два типа: включенные в окончательный пакет приложения (зависимости) и те, которые используются во время разработки, но не включены в окончательный пакет приложения (dev_dependenties). Чтобы понять это различие, давайте рассмотрим в качестве примера пакет flutter_lints. Этот пакет помогает в статическом анализе кода, который выполняется локально на вашем компьютере. Нет необходимости, чтобы он был частью окончательного пакета приложения, распространяемого среди пользователей.

После добавления flutter_lints в ваши dev_dependentities и запуска flutter pub get вы можете проанализировать свой код в соответствии с правилами проверки, заданными flutter_lints, с помощью команды flutter Analysis. Эта команда проверяет ваш код на наличие проблем на основе правил проверки, определенных пакетом.

Чтобы найти новые пакеты, разработчики Flutter часто посещают https://pub.dev. Предположим, вы хотите выполнить сетевой запрос к удаленному серверу с помощью http-пакета. Вы можете просто добавить его в свои зависимости, а затем выполнить flutter pub get, чтобы получить пакет и подготовить его к использованию.

Альтернативно вы можете использовать команду flutter pub add http, чтобы не только загрузить, но и автоматически добавить пакет http в ваши зависимости. Чтобы добавить пакет в dev_dependenties, вы должны использовать flutter pub add --dev package_name.

Экспериментирование с этими методами может помочь вам определить наиболее удобный способ управления пакетами в вашем приложении Flutter.

flutter:
  uses-material-design: true

В конце файла есть раздел с надписью "futter", в котором указана настройка use-material-design: true. Этот конкретный параметр сообщает Flutter, что наше приложение будет использовать стиль Material Design, предоставляя набор рекомендаций по визуальному дизайну, взаимодействию и анимационному дизайну, разработанный Google.

По мере того, как вы углубляетесь в разработку Flutter, вы столкнетесь с рядом дополнительных конфигураций, которые можно применить в этом файле для дальнейшей персонализации тем и других аспектов вашего приложения.

Кроме того, стоит упомянуть файл pubspec.lock, важнейший компонент проектов Flutter. Этот файл автоматически создается Flutter, когда вы запускаете такие команды, как flutter pub get или flutter pub add. Его основная цель — записать точные версии каждой зависимости, используемой в вашем проекте, на момент выполнения этих команд. Это гарантирует, что ваш проект останется согласованным и стабильным, даже если зависимости будут обновлены в будущем. Отслеживая эти версии, файл pubspec.lock помогает предотвратить проблему «он работает на моей машине», гарантируя, что каждый разработчик, работающий над проектом, использует одни и те же версии зависимостей, что сводит к минимуму конфликты и проблемы совместимости.

Специфические для платформы проекты во Flutter

Внутри проекта Flutter, помимо файлов pubspec.yaml и pubspec.lock, вы увидите несколько каталогов, названных в честь платформ. Эти каталоги: android, ios, macos, linux и windows. Это не просто папки; это полноценные собственные проекты для соответствующих платформ.

Сильная сторона Flutter заключается в его способности предоставлять многоплатформенную среду разработки, скрывая сложности деталей реализации для конкретной платформы. Тем не менее, существование этих проектов, ориентированных на конкретную платформу, имеет решающее значение для бесперебойной работы Flutter в различных средах.

Бывают случаи, когда вам нужно погрузиться в нативную разработку в этих каталогах. Часто это тот случай, когда определенная функциональность может быть достигнута только с помощью кода, специфичного для платформы. Именно в таких сценариях становятся необходимыми изменения в исходных частях проекта.

Важно отметить, что вам не обязательно поддерживать все эти каталоги, если ваше приложение не предназначено для всех поддерживаемых платформ. Например, если вы сосредоточены исключительно на Android и iOS, вы можете безопасно удалить каталоги Macos, Linux и Windows.

И наоборот, если вы решите расширить доступность вашего приложения для дополнительных платформ, изначально не включенных в ваш проект, Flutter упростит это расширение. Используя команду flutter create с опцией --platforms, вы можете добавить необходимые проекты платформы. Например, если вы начинаете с проекта, поддерживающего только Android и iOS, а позже решите включить поддержку macOS, Linux и Windows, вы можете выполнить flutter create --platforms=macos, linux, windows. Эта команда создает необходимые каталоги для новых поддерживаемых платформ.

Исходный код вашего приложения: каталог lib.

Мы уже видели основные файлы и каталоги проекта Flutter, хотя я, правда, не перечислил их все, а сейчас описал наиболее важные из них, о которых вам следует знать с самого начала. Теперь давайте перейдем в каталог lib, место, где находится весь код Dart, составляющий ваше приложение.

Когда вы создаете новый проект, Flutter автоматически создает файл main.dart в папке lib. Этот файл содержит исходный код, отвечающий за приложение-счетчик, которое вы увидите, если запустите проект. Если вы войдете, вы увидите комментарии, объясняющие каждый раздел. Как и раньше, мы собираемся исключить эти комментарии и постепенно объясним каждую часть:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

Первая строка представляет импорт material.dart. Этот импорт важен, поскольку по умолчанию мы используем виджеты Material для создания пользовательского интерфейса.

После этого мы встречаем метод main(). Каждому приложению Dart, включая Flutter, требуется точка входа, которая предоставляется функцией main(). Внутри этой функции мы вызываем runApp(), позволяя приложению запуститься. Мы передаем ему экземпляр MyApp, который является следующим виджетом, который мы встретим в файле:

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

В этом фрагменте представлен виджет MyApp, который служит основным элементом вашего приложения. Он находится на вершине иерархии виджетов и по сути действует как корень, от которого будут разветвляться все остальные виджеты. Приложения Flutter структурированы как обширное дерево виджетов, где каждый виджет может быть родительским или дочерним для других. Здесь MyApp выступает в качестве начального узла в этой взаимосвязанной структуре.

MyApp определяется как класс, расширяющий StatelessWidget. StatelessWidgets характеризуются отсутствием внутреннего состояния — они не управляют данными, которые изменяются с течением времени. Следовательно, StatelessWidget не перестраивается в ответ на изменения внутренних данных. Более подробная информация об этом будет предоставлена ​​по мере нашего продвижения.

Каждый StatelessWidget должен реализовать метод Widget build (BuildContext context). В этом методе создается пользовательский интерфейс приложения. В этом примере мы создаем виджет MaterialApp внутри этого метода. MaterialApp облегчает разработку приложения в соответствии с рекомендациями Material Design, включая такие аспекты, как название и тема приложения.

Атрибут home определяет виджет, который будет отображаться при запуске приложения. Здесь для него установлено значение MyHomePage — виджет, который идет следующим в файле:

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

MyHomePage — это виджет, похожий на MyApp, но он наследуется от StatefulWidget, а не от StatelessWidget. Это различие вводит два связанных класса: сам MyHomePage, который настраивает виджет, и _MyHomePageState, класс, который управляет состоянием виджета, расширяя State.

Причина, по которой _MyHomePageState начинается с символа подчеркивания (_), заключается в том, чтобы указать, что этот класс должен быть частным в этом файле.

В классе состояния мы обязаны снова реализовать метод Widget build(BuildContext context). Однако на этот раз это происходит внутри класса состояния, где мы определяем дерево виджетов, составляющее интерфейс счетчика:

  • Изначально виджет Scaffold отображает базовую структуру нашего экрана, учитывая такие элементы, как панели навигации системы.
  • AppBar действует как верхняя панель навигации, где мы указываем заголовок и изменяем цвет фона с помощью тем.
  • Тело Scaffold содержит виджет Center, который обеспечивает центрирование его содержимого на экране. Внутри Центра размещаем Колонку для вертикального расположения виджетов. Этот столбец содержит два виджета «Текст»: один отображает статическое сообщение, а другой — динамическое значение _counter, стилизованное под текущую тему.
  • Свойство floatActionButton объекта Scaffold использует виджет FloatingActionButton. Эта кнопка, расположенная в правом нижнем углу, предназначена для увеличения счетчика при каждом нажатии.

Понимание управления состоянием во Flutter

Теперь, когда мы примерно увидели все, что есть в файле main.dart, давайте по-простому поймем, как Flutter управляет состоянием.

Как я уже говорил, класс _MyHomePageState отвечает за управление состоянием виджета MyHomePage. В данном случае у нас есть приложение с числовым значением, которое увеличивается при нажатии кнопки. Это государство. В частности, переменная, определенная в начале класса:

  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

Когда мы вызываем метод _incrementCounter(), он вызывает метод setState, и внутри него увеличивается значение переменной _counter. Вызывая метод setState, мы обновляем состояние, сообщая Flutter, что оно изменилось, и заставляем метод сборки запускаться снова, но на этот раз с обновленным состоянием. Позже во втором виджете типа Text считывается переменная _counter для отображения значения на экране.

Это очень упрощенное объяснение управления состоянием во Flutter. Давайте проведем эксперимент и добавим следующую строку непосредственно перед тем, как сборка вернет Scaffold:

  @override
  Widget build(BuildContext context) {

    print('State refresh'); // <-- Add this new line

    return Scaffold(

Теперь снова запустите приложение и посмотрите журнал вывода. Вы увидите напечатанную строку «Обновление состояния» при запуске приложения, а также при изменении значения счетчика.

Как видите, это самый простой способ управлять состоянием вашего приложения во Flutter. Кроме того, вы также смогли увидеть роль метода сборки и его важность при составлении интерфейса на основе изменений состояния.

Ваше первое приложение во Flutter: ключевые понятия

Если это ваш первый контакт с Flutter, возможно, на данный момент вы немного перенасыщены таким большим количеством информации, не волнуйтесь, я перечислю ключевые моменты, которые мы увидели на протяжении всей статьи.

  • Проект Flutter содержит файл pubspec.yaml. Он определяет несколько параметров конфигурации, а также список пакетов, используемых проектом.
  • Проект Flutter может содержать несколько подкаталогов, названных в честь платформы, например android или ios. Это собственные проекты, которые Flutter использует для запуска на каждой платформе.
  • Внутри каталога lib мы находим исходный код проекта, именно здесь мы будем писать наши файлы в коде Dart для создания нашего приложения.
  • По своей сути приложение Flutter структурировано как обширная иерархия виджетов. Виджеты могут быть двух типов: StatefulWidget, который хранит состояние (переменные, которые могут меняться со временем), и StatelessWidget, который не хранит состояние.
  • Мы можем изменить состояние StatefulWidget, используя метод setState.

В целом это основные базовые моменты, которые вам следует знать, если вы начинаете разрабатывать приложения с помощью Flutter.

Надеюсь, эта статья была для вас полезна. Не стесняйтесь следить за этим блогом и моим каналом на YouTube, если вы хотите продолжить изучение разработки приложений с помощью Flutter, а также быть в курсе новостей и других интересных тем, связанных с этой великолепной средой.

Спасибо, что дочитали до этого места, удачного кодирования!

Источник:

#Flutter
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу