Начало работы с Flutter Desktop
С момента выпуска Flutter в декабре 2018 года он набрал обороты и быстро становится популярным выбором для многих профессиональных разработчиков мобильных устройств по всему миру.
Опираясь на успех языка Dart и экосистемы Flutter, поддержка настольных компьютеров предоставляет новые возможности для создания великолепных настольных приложений с чистыми и читаемыми кодовыми базами и высокопроизводительными двоичными файлами.
В этой статье мы рассмотрим процесс создания простого desktop приложения с помощью Flutter и рассмотрим возможности и проблемы использования этих инструментов для создания законченных приложений.
Требования
Для создания desktop приложений с помощью Flutter требуется современная среда Flutter SDK с включенной поддержкой рабочего стола:
- Если у вас его еще нет, загрузите Flutter для вашей ОС с их сайта.
- Переключитесь на главный канал с помощью
$ flutter channel master
- Вы можете обновить Flutter (при необходимости) с помощью
$ flutter upgrade
Чтобы включить поддержку для вашей целевой среды:
- Linux:
$ flutter config --enable-linux-desktop
- MacOS:
$ flutter config --enable-macos-desktop
- Window:
$ flutter config --enable-windows-desktop
Команда flutter create
в настоящее время поддерживает все еще не основные операционной системы (по состоянию на декабрь 2019 года) только MacOS. Для получения дополнительной информации о текущем и будущем статусе поддержки настольных компьютеров, можете посетить GitHub.
Настройка проекта
Чтобы создать приложение для macOS, просто запустите, $flutter create
и проект будет создан. Для создания приложения, которое также может поддерживать Linux и Windows, проект Flutter предоставляет стартовый проект, поддерживающий все три среды, с проектом flutter-desktop-embedding.
Он может быть склонирован или загружен для использования в качестве отправной точки для новых проектов.
Пример проекта, использованный в этой статье, был создан путем клонирования рабочего стола флаттера с встраиванием репозитория и копированием содержимого example/
в новый проект. Для получения копии примера кода проекта этой статьи, проверьте этот репозиторий.
Давайте посмотрим на файл определения проекта, pubspec.yaml:
name: example_flutter
description: An example project for Flutter with desktop target support.
version: 0.1.0
environment:
sdk: '>=2.0.0 <3.0.0'
# The example interacts with build scripts on the Flutter side that are not
# yet stable, so it requires a very recent version of Flutter.
# This version will increase regularly as the build scripts change.
flutter: '>=1.10.2-pre.54'
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.0
color_panel:
path: ./plugins/color_panel
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
# See https://github.com/flutter/flutter/wiki/Desktop-shells#fonts
fonts:
- family: Roboto
fonts:
- asset: fonts/Roboto/Roboto-Thin.ttf
weight: 100
- asset: fonts/Roboto/Roboto-Light.ttf
weight: 300
- asset: fonts/Roboto/Roboto-Regular.ttf
weight: 400
- asset: fonts/Roboto/Roboto-Medium.ttf
weight: 500
- asset: fonts/Roboto/Roboto-Bold.ttf
weight: 700
- asset: fonts/Roboto/Roboto-Black.ttf
weight: 900
Для этого и других встроенных проектов для настольных компьютеров требуется последняя версия Flutter. В дополнение к нескольким типовым шрифтам была включена зависимость для простого Desktop плагина - нативная палитра цветов. Далее мы проверим код Dart для этого простого одноэкранного демонстрационного приложения.
Точка входа в приложение
Основной файл для этого приложения - стандартный lib/main.dart :
import 'package:example_flutter/home.dart';
import 'package:flutter/foundation.dart' show debugDefaultTargetPlatformOverride;
import 'package:flutter/material.dart';
void main() {
debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Desktop Example',
theme: ThemeData(
primarySwatch: Colors.indigo,
fontFamily: 'Roboto',
),
darkTheme: ThemeData.dark(),
home: Home(title: 'Flutter Desktop Example'),
);
}
}
Функция main()
запускает приложение и устанавливает целевую платформу отладки по умолчанию на fuchsia, которая представляет собой ОС, разрабатываемую в Google и включающую пользовательский интерфейс, созданный с помощью Dart и Flutter. Класс MyApp - это базовая реализация StatelessWidget, которая возвращает основной контейнер для самого приложения, со стандартом заголовка, темы и домашнего виджета для любого приложения Flutter.
Обратите внимание, что свойство darkTheme
и его значение ThemeData.dark()
обеспечивают темную тему, когда она запрашивается операционной системой, как в случае macOS с включенной темной темой для всей системы. Далее мы рассмотрим содержание страницы примера и ее назначение.
Домашний экран
Большая часть содержимого приложения для этой простой демонстрации находится в lib/home.dart
:
import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:color_panel/color_panel.dart';
class Home extends StatefulWidget {
Home({Key key, this.title}) : super(key: key);
final String title;
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State {
int _counter = 0;
Color _color = Colors.white;
void _increment() => setState(() { _counter++; });
void _decrememt() => setState(() { _counter--; });
void _showPanel() {
final colorPanel = ColorPanel.instance;
if (colorPanel.showing) return;
colorPanel.show(this._onGetColor, showAlpha: false);
}
void _onGetColor(Color color) => setState(() { _color = color; });
@override
Widget build(BuildContext context) {
final TextTheme _theme = Theme.of(context).textTheme;
final TextStyle _style1 = _theme.body1.copyWith(color: _color);
final TextStyle _style2 = _theme.display1.copyWith(color: _color);
final String _os = Platform.operatingSystem;
final String _hostname = Platform.localHostname;
final String _numCores = Platform.numberOfProcessors.toString();
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FlatButton.icon(
label: Text('Set Color'),
icon: Icon(Icons.color_lens),
onPressed: _showPanel,
clipBehavior: Clip.none,
),
FlatButton.icon(
label: Text('Counter +'),
icon: Icon(Icons.add_circle),
onPressed: _increment,
clipBehavior: Clip.none,
),
FlatButton.icon(
label: Text('Counter -'),
icon: Icon(Icons.remove_circle),
onPressed: _decrememt,
clipBehavior: Clip.none
)
]
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("OS: " + _os, style: _style1),
Text('Hostname: ' + _hostname, style: _style1),
Text('CPU Cores: ' + _numCores, style: _style1),
Text('$_counter', style: _style2)
]
)
]
)
);
}
}
В Home
мы импортируем несколько пакетов (включая плагин color_panel
) и реализуем StatefulWidget, чтобы этот экран был в состоянии хранить и обновлять приложения. Dart и Flutter предоставляют отличные возможности для управления состоянием с использованием различных инструментов и шаблонов, самым простым из которых является виджет с состоянием, подобный показанному в этом файле.
Свойства, управляемые в состоянии этого виджета, включают цвет и счетчик. Методы _increment
и _decrement
используют метод setState
для увеличения или уменьшения счетчика. Метод _showPanel
запрашивает экземпляр ColorPanel из импортируемого плагина, а затем вызывает на нем show
, который будет запрашивать нативный выбор цвета из операционной системы. Когда выбран цвет, setState
используется для обновления состояния виджета новым цветом, который ставит его в очередь для перерисовки движком Flutter.