Инструкции для этой демонстрации будут максимально общими и простыми для выполнения. Будем использовать Movie Picker, вы можете включить его в любой проект Flutter, который пожелаете. В конце будет краткий обзор того, как может выглядеть стилизованная и полностью реализованная версия этой функции с помощью Movie Picker.
В этом уроке будем использовать пакет flutter_widgetkit. Этот пакет невероятно прост в использовании, но его возможности ограничены созданием только виджетов домашнего экрана iOS. Однако в вашем распоряжении есть несколько других пакетов, таких как home_widget, который позволяет создавать виджеты как для iOS, так и для Android, но по сути все они функционируют одинаково для iOS.
Прежде чем начать, убедитесь, что у вас выполнены следующие условия:
Шаг 1. Настройте проект Flutter
Если вы еще этого не сделали, создайте новый проект Flutter или используйте существующий. Откройте проект в предпочитаемом редакторе кода. Автор использует Android Studio.
Шаг 2. Добавьте зависимости
В свой pubspec.yaml добавьте пакет flutter_widgetkit:
dependencies:
flutter:
sdk: flutter
flutter_widgetkit: ^1.0.3 # Use the latest version
Шаг 3. Создание домашней страницы
Начнем с создания простого домашнего экрана Flutter. Он будет содержать ElevatedButton и простой файл TextField. Все, что нужно от этой страницы, — это принимать текст в качестве входных данных из TextField, и при нажатии кнопки нужно, чтобы наш виджет iOS обновлялся.
var textController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 250,
child: TextField(
controller: textController,
decoration: InputDecoration(
hintText: "Enter widget text",
),
),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () {},
child: const Text("Send to Widget"),
),
],
),
),
);
}
Шаг 4. Создание WidgetData
Чтобы упростить отправку данных в iOS-виджет, создадим простой WidgetData. Нужно отправить экземпляр класса данных в виде строки JSON, которая может быть проанализирована кодом SwiftUI. На данный момент этот класс содержит только одну переменную — строку с именем text, но она может содержать любые произвольные данные, которые вы хотите отправить в свой виджет.
class WidgetData {
final String text;
WidgetData(this.text);
WidgetData.fromJson(Map<String, dynamic> json) : text = json['text'];
Map<String, dynamic> toJson() => {'text': text};
}
Шаг 5: Отправка информации
Используем WidgetKit.setItem() для отправки данных в виджет. Для этого метода потребуется key, который будет на стороне Xcode, и значение value будет данными, которые нужно отправить. Важно предоставить группу приложений, которую настроим в XCode всего за секунду, используем group.flutterioswidget.
ElevatedButton(
onPressed: () {
WidgetKit.setItem(
'widgetData',
jsonEncode(WidgetData(textController.text)),
'group.flutterioswidget');
WidgetKit.reloadAllTimelines();
},
child: const Text("Push to Widget"),
),
Вызываем WidgetKit.reloadAllTimelines(), он перезагрузит временную шкалу и произойдет перерисовка нашего виджета.
Шаг 7: Создайте новую цель
Нажмите Runner, а затем в левом нижнем углу нажмите кнопку «плюс» (+), чтобы создать новую цель.
Найдите «Расширение виджета» и щелкните результат.
Введите любое имя и нажмите «Готово».
Шаг 8. Назначьте группы приложений
Прежде чем перейти к следующему шагу, нужно назначить AppGroups этим целям. В разделе «Targets» выберите цель виджета, которая была недавно создана, и нажмите плюс (+) рядом с надписью «Capability», чтобы добавить новую. Найдите «AppGroup» и выберите первый результат.
Создайте новую группу приложений, нажав кнопку «плюс» (+). Группа приложений должна начинаться с .group, и очень важно, чтобы это соответствовало тому, что вы указали в коде Flutter.
Теперь нужно добавить такую же возможность Runner. Нажмите на Runner в Targets и повторите шаги, описанные выше.
Теперь всё готово, чтобы принимать данные из нашего приложения Flutter!
Шаг 9. Перейдите к коду виджета
Перейдите к FlutterIOSWidget (или к тому, в котором есть Provider).
Шаг 10. Создание виджета SwiftUi
В нашем примере будет только одна запись данных, а именно строка с именем text.
struct WidgetData: Decodable, Hashable {
let text: String
}
Далее нужно создать TimelineEntry, назовем его FlutterEntry:
struct FlutterEntry: TimelineEntry {
let date: Date
let widgetData: WidgetData?
}
Теперь нужно создать файл Provider. Если вы знакомы со SwiftUI, в этом нет ничего нового. Обратите внимание, что AppGroup, указанная в sharedDefaults, должна совпадать везде, где она была указана.
В getTimeline также создаём новый экземпляр flutterData.
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> FlutterEntry {
FlutterEntry(date: Date(), widgetData: WidgetData(text: "Flutter iOS widget!"))
}
func getSnapshot(in context: Context, completion: @escaping (FlutterEntry) -> ()) {
let entry = FlutterEntry(date: Date(), widgetData: WidgetData(text: "Flutter iOS widget!"))
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
let sharedDefaults = UserDefaults.init(suiteName: "group.flutterioswidget")
let flutterData = try? JSONDecoder().decode(WidgetData.self, from: (sharedDefaults?
.string(forKey: "widgetData")?.data(using: .utf8)) ?? Data())
let entryDate = Calendar.current.date(byAdding: .hour, value: 24, to: Date())!
let entry = FlutterEntry(date: entryDate, widgetData: flutterData)
let timeline = Timeline(entries: [entry], policy: .atEnd)
completion(timeline)
}
}
Ниже показано, что виджет просто принимает текст, который был установлен из виджета Flutter, и отображает его.
struct FlutterIOSWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
Text(entry.widgetData?.text ?? "Tap to set message.")
}
}
struct FlutterIOSWidget: Widget {
let kind: String = "FlutterIOSWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
FlutterIOSWidgetEntryView(entry: entry)
}
.configurationDisplayName("Flutter iOS Widget")
.description("This is an example Flutter iOS widget.")
}
}
Вот тут и начинается самое интересное, потому что, обладая небольшими знаниями SwiftUI, можно создать абсолютно любой виджет на основе данных, полученных от приложения Flutter.
На этом всё! Полный пример можно посмотреть на github.
Надеюсь, вам было интересно! Подписывайтесь на наш телеграм-канал Flutter. Много, который мы ведем командой мобильных разработчиков. Рассказываем про свой личный опыт и делимся советами от софт-скиллов до технических знаний.