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

Flutter - это кроссплатформенный фреймворк, который позволяет писать приложения для iOS и Android с использованием единой кодовой базы.

По умолчанию приложения Flutter не используют какой-либо определенный шаблон дизайна. Это означает, что разработчик отвечает за выбор и реализацию шаблона, который соответствует их потребностям. Декларативный характер Flutter делает его идеальным кандидатом для шаблона проектирования MVVM.

Понимание MVVM

MVVM расшифровывается как Model-View-ViewModel. Основная идея - создать модель представления, которая будет предоставлять данные для представления. Представление может использовать данные, предоставленные моделью представления, для своего заполнения. Создание уровня модели представления позволяет писать модульный код, который может использоваться несколькими представлениями.

Шаблон проектирования MVVM был разработан корпорацией Майкрософт. MVVM активно использовался при написании приложений Windows Presentation Foundation (WPF). Паттерн MVVM - это причудливое название для PresentationModel.



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

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

Реализация веб-сервиса

Мы будем использовать API OMDb для загрузки фильмов. Убедитесь, что вы зарегистрировались на их веб-сайте, чтобы получить ключ API. Без действующего ключа API вы не сможете выполнить успешный запрос.

Теперь, когда вы зарегистрировались в службе OMDb и получили свой ключ, мы можем перейти к реализации веб-службы / клиента. Веб-служба использует пакет HTTP для выполнения сетевого запроса и загрузки ответа JSON, но вы можете свободно использовать любой сетевой пакет, который вам нужен.

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

Модель фильма реализована ниже:

Movie просто состоит из заголовка и плаката. Он также предоставляет функцию fromJson, которая позволяет нам создать объект Movie на основе ответа JSON.

Мы использовали термин модель для определения наших Movie объектов, но на самом деле они служат объектам передачи данных (DTO).

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

Реализация моделей представления

Хотя вы можете достичь желаемого результата, создав единую модель представления, мы создадим две отдельные модели представления в нашем приложении.

Одна модель просмотра, MoviesListViewModel, будет представлять весь экран отображения фильмов. Вторая модель представления, MovieViewModel, будет представлять отдельный фильм, который будет отображаться в представлении.

Реализация моделей представления показана ниже:

MovieListViewModel состоит из свойства movies, которое будет возвращать список объектов MovieViewModel. MovieViewModel принимает объект Movie и возвращает заголовок и плакат как свойства только для чтения. Следующим шагом является получение фильмов с помощью веб-службы.

Настройка ChangeNotifier и ChangeNotifierProvider

Метод fetchMovies в MovieListViewModel отвечает за получение фильмов из API OMDb с помощью веб-службы.

Реализация показана ниже:

Мы обновили наш MovieListViewModel, чтобы он унаследовал от ChangeNotifier. ChangeNotifier позволяет нам публиковать уведомления об изменениях, которые может использовать представление для самообновления.

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

Чтобы уведомить представление об обновленном MovieListViewModel, нам нужно будет использовать ChangeNotifierProvider ,, который является частью пакета Provider. Добавьте пакет поставщика, добавив зависимость в файл pubspec.yaml, как показано ниже:

Затем нам нужно найти хорошее место для ввода значения от поставщика. Значение, о котором мы говорим, является экземпляром MovieListViewModel, поскольку оно расширяет ChangeNotifier и публикует уведомления для слушателей.

В нашем случае мы можем использовать файл main.dart и вставить значение в MovieListPage. Это означает, что MovieListViewModel будет доступен MovieListPage и всем его дочерним элементам.

Потрясающие. Последний шаг - вывести данные на экран. Это рассматривается в следующем разделе.

Показ фильмов

В нашем приложении мы попросим пользователя ввести ключевое слово и нажать клавишу возврата на клавиатуре. Это вызовет метод fetchMovies на MovieListViewModel, как показано ниже:

fetchMovies будет извлекать все фильмы на основе ключевого слова и запускать notifyListeners. Чтобы получить обновленный экземпляр MovieListViewModel, нам поможет пакет поставщика, как показано ниже:

@override Widget build(BuildContext context) { 
final vm = Provider.of<MovieListViewModel>(context);

Добавляя Provider в метод сборки, мы гарантируем, что всякий раз, когда notifyListener запускается, у нас есть доступ к экземпляру MovieListViewModel.

Теперь, если вы запустите приложение, оно получит фильмы на основе ключевого слова и отобразит их в пользовательском интерфейсе.

Если вы хотите выполнить начальную выборку при загрузке страницы, вы можете обновить свой StatelessWidget до StatefulWidget и вызвать fetchMovies из метода initState, как показано ниже:

Обратите внимание, что мы передаем listen: false вместо Provider, что означает, что это только одноразовый вызов, и изменения не будут отслеживаться Provider.

Посмотреть репозиторий GitHub можно здесь.



Спасибо за прочтение!