У вас включен AdBlock или иной блокировщик рекламы.

Пожалуйста, отключите его, доход от рекламы помогает развитию сайта и появлению новых статей.

Спасибо за понимание.

В другой раз
DevGang блог о програмировании
Авторизоваться

Начало работы с Flutter Desktop 

С момента выпуска Flutter в декабре 2018 года он набрал обороты и быстро становится популярным выбором для многих профессиональных разработчиков мобильных устройств по всему миру.

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

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

Требования

Для создания desktop приложений с помощью Flutter требуется современная среда Flutter SDK с включенной поддержкой рабочего стола:

  1. Если у вас его еще нет, загрузите Flutter для вашей ОС с их сайта.
  2. Переключитесь на главный канал с помощью $ flutter channel master
  3. Вы можете обновить Flutter (при необходимости) с помощью $ flutter upgrade

Чтобы включить поддержку для вашей целевой среды:

  1. Linux: $ flutter config --enable-linux-desktop
  2. MacOS: $ flutter config --enable-macos-desktop
  3. Window: $ flutter config --enable-windows-desktop

Команда flutter create в настоящее время поддерживает все еще не основные операционной системы (по состоянию на декабрь 2019 года) только MacOS. Для получения дополнительной информации о текущем и будущем статусе поддержки настольных компьютеров, можете посетить GitHub.

Настройка проекта

Чтобы создать приложение для macOS, просто запустите, $flutter create и проект будет создан. Для создания приложения, которое также может поддерживать Linux и Windows, проект Flutter предоставляет стартовый проект, поддерживающий все три среды, с проектом flutter-desktop-embedding.

Он может быть склонирован или загружен для использования в качестве отправной точки для новых проектов.

Пример проекта, использованный в этой статье, был создан путем клонирования рабочего стола флаттера с встраиванием репозитория и копированием содержимого example/ в новый проект. Для получения копии примера кода проекта этой статьи, проверьте этот репозиторий.

Давайте посмотрим на файл определения проекта, pubspec.yaml:

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 :

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<Home> {

    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: <Widget>[
                    Column(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: <Widget>[
                            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: <Widget>[
                            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.

Источник:

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

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

Попробовать