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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

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

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

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

Посмотреть вторую версию системы (то что готово) и понажимать на кнопки можно тут.

Доступ в систему

Логин operator@mail.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">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/request_status/failure_canceled.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/request_status/failure_done.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/request_status/in_progress.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/request_status/paid_cancelled.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/request_status/paid_done.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/request_status/received.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/arrow_left.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/arrow_right.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/back_arrow.png">
  <link rel="icon" type="image/png" sizes="48x48" href="icons/clock.png">
  <link rel="icon" type="image/png" sizes="40x40" href="icons/dropdown_arrow.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/eye_green.png">
  <link rel="icon" type="image/png" sizes="512x512" href="icons/eye.png">
  <link rel="icon" type="image/png" sizes="52x52" href="icons/image.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>
  1. Открываем далее 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 виджет. Выглядит теперь не совсем по дизайну, но за то меньше проблем, на мой взгляд.

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

extension 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х и т.д.);

  • упрощенную процедуру деплоя очередной сборки на сервер.

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

Источник: https://habr.com/ru/post/685772/


Интересные статьи

Интересные статьи

Из нового мысленного эксперимента следует, что квантовая механика не работает без использования этих странных чисел, становящихся отрицательными при возведении в квадрат Несколько де...
Менторство — это не просто история про обмен опытом, а ментор — не просто наставник. Это человек, который передает вам опыт своих профессиональных побед и поражений, дост...
Год назад я пришел в vivid.money третьим разработчиком. Несмотря на это, в проекте практически не было кода, а первые фичи только начинали разрабатываться. Уже тогда было понятно, что ком...
Когда-то я проходил серию собеседований на Backend-Java-разработчика и записывал вопросы себе на будущее, чтобы потом можно было пробежаться и освежить память. Подумалось, что, вероятно...
Это заключительная часть лаконичной интерпретации документации по Flutter, которая будет полезна Xamarin.Forms-разработчикам. Учитывая текущую ситуацию, сейчас самое время изучать что-то новое! П...