{"id":13657,"url":"\/distributions\/13657\/click?bit=1&hash=566d340c54b853eeeda9db62318bf71978b30f8d7cf7d9099caa6c0c5d13ed5b","title":"\u041a\u0430\u043a \u0434\u0438\u0432\u0435\u0440\u0441\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0440\u0442\u0444\u0435\u043b\u044c? \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u00ab\u0437\u0435\u043b\u0451\u043d\u044b\u043c\u0438\u00bb \u043e\u0431\u043b\u0438\u0433\u0430\u0446\u0438\u044f\u043c\u0438","buttonText":"\u0423\u0437\u043d\u0430\u0442\u044c","imageUuid":"d34c044f-5676-50b8-b978-ab47dfaf9fed","isPaidAndBannersEnabled":false}
Оператор 18

Вопрос использования ассетов в Flutter web проекте

Всем доброго дня!

Меня зовут Алексей, я основатель и frontend разработчик системы автоматизации работы управляющих компаний «Оператор 18».

Сейчас я переписываю проекта с нуля, с учётом ошибок применения архитектуры и структуры самого проекта.

Посмотреть вторую версию системы (то что готово) и понажимать на кнопки можно тут. Доступ в систему: Логин [email protected] ru, пароль: operator.

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

В этой статье я хочу рассказать об опыте применения ассетов (assets), а именно картинок для web приложения написанного на фреймворке Flutter.

В системе «Оператор 18» основным элементом является реестр заявок. Выглядит он следующим образом:

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

Все изображения статусов — это png картинки, которые я добавил в проект, а именно — в папку assets/icons в корне проекта. И еще прописал зависимости в pubspec.yaml:

... flutter: uses-material-design: true assets: - assets/icons/ ...

В самом коде я получаю картинку просто обращаясь к текущему статусу заявки и, в зависимости от статуса, геттер отдает мне ту или иную картинку:

extension StatusIcon on UserRequest { Widget? get requestStatusIcon { if (status == RS.received) { return Image.asset( 'icons/request_status/received.png', ); } if (status == RS.inProgress) { return Image.asset( 'icons/request_status/in_progress.png', ); } // и так далее, аналогично отдавал нужные картинки } }

Ну, кажется всё! Бидлим проект, загружаем на сервер и… получаем следующий результат:

Как видно, ни одна картинка не подгрузилась. Но если открыть консоль Google Chrome, станет сразу понятно, что браузер не знает где взять эти самые картинки (хоть они и есть на сервере).

Чтобы это поправить, нужно прописать ещё некоторые моменты, а именно:

1 Открываем файл web/index. html и добавляем описание картинок в него:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="description" content="Управляющая компания"> <!-- iOS meta tags & icons --> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-title" content="Управляющая компания"> <link rel="apple-touch-icon" href="icons/Icon-192.png"> <!-- Ниже указываем все кастомные картинки которые используются в проекте, из разрешение и пусть к ним --> <link rel="icon" type="image/png" sizes="512x512" href="icons/request_status/cancelled.png"> <link rel="icon" type="image/png" sizes="512x512" href="icons/request_status/common_done.png"> <!-- и так далее... --> <!-- Дальше идет код стандартный для index.html файла Flutter проекта --> <!-- Favicon --> <link rel="shortcut icon" type="image/png" href="favicon.png" /> <link rel="stylesheet" href="loader.css"> <title>Управляющая компания</title> <link rel="manifest" href="manifest.json"> </head> <body> // ... </body> </html>

2 Открываем далее web/manifest. json и добавляем следующий код:

{ "name": "Управляющая компания", "short_name": "Управляющая компания", "start_url": ".", "display": "standalone", "background_color": "#0175C2", "theme_color": "#0175C2", "description": "Управляющая компания", "orientation": "portrait-primary", "prefer_related_applications": false, "icons": [ // прописываем место расположения картинки и размер { "src": "icons/Icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "icons/Icon-512.png", "sizes": "512x512", "type": "image/png" }, { "src": "icons/request_status/cancelled.png", "sizes": "512x512", "type": "image/png" }, // ... и так далее по всем картинкам которые есть ] }

Снова билдим и деплоим на сервер. Теперь картинки загружаются!

Но некоторые картинки в итоге выглядят не очень хорошо, как будто бы разрешение картинки не подходит для разрешения экрана. К слову сказать, я использую flutter_screenutil, и размер экрана выбран 1920 х 1080 пикселей (может быть в этом проблема).

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

Сама иконка статуса теперь оформлена следующим образом:

xtension StatusIcon on UserRequest { Widget? get requestStatusIcon { if (status == RS.received) { return Container( alignment: Alignment.center, height: 32.h, width: 32.w, decoration: BoxDecoration( color: AppColors.grey_1, borderRadius: BorderRadius.circular(8.r), ), // иконка для статуса "Получна" child: Icon( Icons.inbox_outlined, color: AppColors.grey_2, size: 20.w, ), ); } // контейнеры с иконками для других статусов... } }

А страница с заявками выглядит так:

По итогу, я получил:

  • экономию времени;
  • отсутсвие необходимости контроля множества файлов;
  • отсутсвие необходимости использовать множество картинок для разных разрешений экрана (1х, 2х и т. д.);
  • упрощенную процедуру деплоя очередной сборки на сервер.

Спасибо за прочтение! Буду благодарен за критику/советы/иные комментарии.

0
Комментарии
Читать все 0 комментариев
null