Як зосереджувати векторний малюнок у списку шарів без масштабування


102

Я намагаюсь використовувати " VectorDrawablea" LayerListбез масштабування вектора. Наприклад:

<layer-list>
    <item android:drawable="@color/grid_item_activated"/>
    <item android:gravity="center" android:drawable="@drawable/ic_check_white_48dp"/>
</layer-list>

Витяжка ic_check_white_48dpідентифікатор визначається як:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="48dp"
        android:height="48dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FFFFFFFF"
        android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

Бажаний ефект полягає у тому, щоб піктограма була відцентрована в шарі, що малюється, без масштабування. Проблема полягає в тому, що вищевказаний список шарів викликає масштаб піктограми, щоб відповідати розміру шару.

Я можу створити бажаний ефект, якщо заміню векторний малюнок на PNG для кожної щільності і зміню список шарів як такий:

<layer-list>
    <item android:drawable="@color/grid_item_activated"/>
    <item>
        <bitmap android:gravity="center" android:src="@drawable/ic_check_white_48dp"/>
    </item>
</layer-list>

Чи є спосіб зробити це за допомогою VectorDrawable?


11
Схоже, це може бути просто помилка в API 21/22. Я щойно тестував на пристрої API 23, і вектор, що малюється, був правильно зосереджений.
ashughes

1
Ви повинні відповісти на власне питання і прийняти його. Таким чином воно стає більш помітним, і питання не відображається як без відповіді.
Марцін Козінський

1
Я не відповів на моє запитання, оскільки ще не маю відповіді, що робити в API 21/22. Моє тимчасове рішення - використовувати PNG замість векторів. Сподіваючись, що все ж знайти спосіб змусити вектори працювати.
ashughes

1
Я відкрив тут проблему: code.google.com/p/android/isissue/detail?id=219600
toobsco42

Це вже виправлено в API 23, тому я гадаю, що ваш звіт про помилку буде позначений як виправлений.
ashughes

Відповіді:


29

Я зіткнувся з тією ж проблемою, намагаючись зосередити вектори малюнків на багатошаровому списку.

У мене є вирішення, воно не зовсім те саме, але воно працює, вам потрібно встановити розмір для всього малювання та додати вкладку до векторного елемента:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <size android:height="120dp" android:width="120dp"/>
            <solid android:color="@color/grid_item_activated"/>
        </shape>
    </item>
    <item android:top="24dp"
          android:bottom="24dp"
          android:left="24dp"
          android:right="24dp"
          android:drawable="@drawable/ic_check_white_48dp"/>
</layer-list>

Розмір фігури вище задає розмір всього малюючого, 120dp у цьому прикладі, накладка на другому елементі, 24dp у цьому прикладі, центрирує векторне зображення.

Це не те саме, як використання, gravity="center"але робочий спосіб використання векторів в API 21 і 22.


2
Це звучить так, як би вимагало, щоб ви дізналися точний розмір рисунка (для того, щоб встановити розмір форми), а не дозволяти йому заповнити весь простір, на який він заданий, за допомогою чека, який можна намалювати по центру.
ashughes

1
можливо не знати розміру, але ви не можете змінити підкладку за допомогою цього методу, ви можете нанести натягуючі елементи один на одного в режимах перегляду зображень. Як я вже говорив вище, немає ідеального рішення для gravity="center"API 21 і 22.
Ніколя Тайлер

Це не працює при використанні з windowBackground. Явні розміри в цьому випадку нічого не роблять. І це не працює, якщо я поміщаю список шарів всередині іншого списку шарів.
Всеволод Ганін

19

Боровся з тією ж проблемою. Єдиний спосіб, як я вирішив це виправити та уникнути збільшення масштабу, який можна змінити, - це встановити розмір зображуваного розміру та за допомогою гравітації вирівняти його:

<layer-list>
    <item android:drawable="@color/grid_item_activated"/>
     <item
        android:gravity="center"
        android:width="48dp"
        android:height="48dp"
        android:drawable="@drawable/ic_check_white_48dp"/>
</layer-list>

Сподіваюся, це допомагає!


34
Це не допомагає для API 21-22, оскільки widthатрибут недоступний на цих рівнях API. Для API 23 вони не потрібні, оскільки помилка виправлена, а перетягується більше не розтягується.
WonderCsabo

3
Це не працює належним чином для API 27, зображення розтягується на повноекранний екран
Костянтин Конопко

8

Відредаговане рішення, яке зробить ваш SplashScreen чудовим для всіх API, включаючи API21 до API23

Перш за все прочитайте цю статтю та дотримуйтесь ДОБРОГО способу виготовлення екрана.

Якщо ваш логотип перекручений або не підходить, і ви орієнтуєтесь лише на API24 +, ви можете просто масштабувати векторний малюнок прямо у своєму XML-файлі так:

<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="640"
android:viewportHeight="640"
android:width="240dp"
android:height="240dp">
<path
    android:pathData="M320.96 55.9L477.14 345L161.67 345L320.96 55.9Z"
    android:strokeColor="#292929"
    android:strokeWidth="24" />
</vector>

у наведеному вище коді я переглядаю малюнок, що малюється на малюнку, я намалював на полотні 640x640 розмір 240x240. то я просто помістив його у свій сплеск-екран, малюючи так, і він чудово працює:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque"
android:paddingBottom="20dp" android:paddingRight="20dp" android:paddingLeft="20dp" android:paddingTop="20dp">

<!-- The background color, preferably the same as your normal theme -->
<item>
    <shape>
        <size android:height="120dp" android:width="120dp"/>
        <solid android:color="@android:color/white"/>
    </shape>
</item>

<!-- Your product logo - 144dp color version of your app icon -->
<item
    android:drawable="@drawable/logo_vect"
    android:gravity="center">

</item>
</layer-list>

мій код насправді лише малювання трикутника на малюнку внизу, але тут ви бачите, чого ви можете досягти з цим. Роздільна здатність нарешті велика на відміну від пікселізованих країв, які я отримував під час використання растрової карти. тому використовуйте вектор, який можна перетягнути всіма способами (є сайт, який називається vectr, який я використовував для створення шахти без хелела для завантаження спеціалізованого програмного забезпечення).

EDIT, щоб він також працював на API21-22-23

Хоча рішення вище працює для пристроїв, що управляють API24 +, я дуже розчарувався, встановивши свій додаток на пристрій під керуванням API22. Я помітив, що бризки екрана знову намагаються заповнити весь погляд і виглядають як лайно. Після того, як я розірвав брови на півдня, я нарешті жорстоко примусив рішення за допомогою чистої сили волі.

вам потрібно створити другий файл, названий точно так само, як splashscreen xml (скажімо, splash_screen.xml) і помістити його у дві папки, звані dravable-v22 та dravable-v21, які ви створите у res / folder (для того, щоб побачити їх ви повинні змінити подання проекту з Android на Project). Це служить для того, щоб ваш телефон перенаправляв на файли, розміщені в цих папках, коли відповідний пристрій запускає API, відповідний суфіксу -vXX у папці, що перетягується, див. Це посилання . розмістіть такий код у списку шарів файлу splash_screen.xml, який ви створюєте у цих папках:

<item>
<shape>
    <size android:height="120dp" android:width="120dp"/>
    <solid android:color="@android:color/white"/>
</shape>
</item>

<!-- Your product logo - 144dp color version of your app icon -->
<item android:gravity="center">
    <bitmap android:gravity="center"
        android:src="logo_vect"/>

</item>

ось так виглядають папки

Чомусь для цих API вам потрібно загорнути малюнок у растрову карту, щоб змусити його працювати і струмувати, щоб кінцевий результат виглядав так само. Проблема полягає в тому, що вам доведеться використовувати aproach з додатковими перетягуваними папками, оскільки друга версія файлу splash_screen.xml призведе до того, що ваш екран сплеску взагалі не відображатиметься на пристроях, на яких працює API більше 23 років. Можливо, вам доведеться розмістити Перша версія splash_screen.xml в dravable-v24 як андроїд за замовчуванням до найближчої папки dravable-vXX, яку вона може знайти для ресурсів.

мій splashscreen


4

В даний час я працюю на екрані заставки з векторним малюнком, орієнтованим як по горизонталі, так і по вертикалі. Ось що я отримав на рівні 25 API:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">

<!-- background color, same as theme -->
<item android:drawable="@android:color/white"/>

<!-- app logo -->

<item
    android:drawable="@drawable/my_app_logo"
    android:gravity="center_horizontal|center_vertical"
    android:width="200dp"
    android:height="200dp"
    />
</layer-list>

Якщо ви хочете відрегулювати розмірність векторного малювання, змініть android:widthтаandroid:height атрибути вище, необов'язково змінювати оригінальний малювальний рисунок.

Крім того, мій досвід - НЕ поміщайте векторний малюнок у тег растрової карти, який ніколи не працює для мене. Растрова карта призначена для файлу формату .png, .jpg та .gif, а не для векторного малювання.

Довідково

https://developer.android.com/guide/topics/resources/drawable-resource#LayerList

https://developer.android.com/guide/topics/resources/more-resources.html#Dimension


1
Хороша інформація про векторні чернетки, які потребують тегу <item> замість тегу <bitmap>.
FrostRocket
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.