Почему мой вектор не рисуется масштабирование, как ожидалось?



Я пытаюсь использовать векторные чертежи в моем приложении для Android. От http://developer.android.com/training/material/drawables.html (Курсив мой):




В Android 5.0 (уровень API 21) и выше, вы можете определить векторные чертежи, масштаб без потери четкости.




С помощью этого drawable:



<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="@color/colorPrimary" android:pathData="M14,20A2,2 0 0,1 12,22A2,2 0 0,1 10,20H14M12,2A1,1 0 0,1 13,3V4.08C15.84,4.56 18,7.03 18,10V16L21,19H3L6,16V10C6,7.03 8.16,4.56 11,4.08V3A1,1 0 0,1 12,2Z" />




и это ImageView:



<ImageView
android:layout_width="400dp"
android:layout_height="400dp"
android:src="@drawable/icon_bell"/>


создает это размытое изображение при попытке отобразить значок в 400dp (на большом мобильном устройстве с высоким разрешением около 2015 года под управлением lollipop):



blurryBellIcon



изменение ширины и высоты в определении вектора drawable до 200dp значительно улучшает ситуацию при 400dp отрисованном размере. Однако, установив это как drawable для элемента TextView (т. е. значок слева от текста) теперь создает огромный значок.



мои вопросы:



1) Почему спецификация ширины / высоты в векторе drawable? Я думал, что весь смысл в том, что они масштабируются вверх и вниз без потерь, делая ширину и высоту бессмысленными в ее определении?



2)Можно ли использовать один вектор drawable, который работает как 24dp drawable на TextView, но хорошо масштабируется, чтобы использовать как можно больше изображений? Например, как избежать создания нескольких векторных чертежей разных размеров и вместо этого использовать тот, который масштабируется до моего рендеринга требования?



3) Как эффективно использовать атрибуты width/height и в чем разница с viewportWidth/Height?



дополнительная информация:




  • устройство работает API 22

  • использование Android Studio v1.5. 1 с Gradle версии 1.5.0

  • Манифест компилируется и целевой уровень 23, минимальный уровень 15. Я также попытался переместить минимальный уровень до 21, но это не имело никакого значения.

  • Декомпиляция APK (с Мин уровень установлен на 21)показывает один XML-ресурс в папке drawable. Растрированные изображения не создаются.

709   7  

7 ответов:

появилась новая информация об этой проблеме здесь:

https://code.google.com/p/android/issues/detail?id=202019

похоже на использование android:scaleType="fitXY" сделает его масштаб правильно на леденец.

от инженера Google:

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

зефир против леденца на палочке из-за специальной обработки масштабирования добавить в зефир.

кроме того, для ваших комментариев: "правильное поведение: вектор рисуется следует масштабировать без потери качества. Поэтому, если мы хотим использовать один и тот же актив в 3 разных размерах в нашем приложении нам не нужно дублировать vector_drawable.xml 3 раза с различными жестко закодированными размерами. "

хотя я полностью согласен, что это должно быть так, на самом деле, Платформа Android имеет проблемы с производительностью, которые мы не достигли идеальный мир еще. Поэтому рекомендуется использовать 3 разных vector_drawable.xml для повышения производительности, если вы уверены, что хотите нарисовать 3 разных размера на экране одновременно.

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

1) Почему существует спецификация ширины/высоты в векторе drawable? Я думал, что весь смысл в том, что они масштабируются вверх и вниз без потерь, делая ширину и высоту бессмысленными в ее определении?

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

2) Можно ли использовать один вектор drawable, который работает как 24dp drawable на TextView, а также большое изображение ширины рядом с экраном?

Я не верю, что это возможно, если вам также нужно нацелить SDK менее 21.

3) Как эффективно использовать атрибуты width/height и в чем разница с viewportWidth/Height?

документы: (на самом деле не очень полезно теперь, когда я перечитал его...)

android:width

используется для определите внутреннюю ширину рисуемого объекта. Это поддерживает все единицы измерения, обычно заданные с помощью dp.

android:height

используется для определения собственной высоты чертежа. Это поддерживает все единицы измерения, обычно заданные с помощью dp.

android:viewportWidth

используется для определения ширины области просмотра пространства. Видовой экран-это в основном виртуальный холст, на котором рисуются пути.

android:viewportHeight

используется для определения высоты области просмотра пространства. Видовой экран-это в основном виртуальный холст, на котором рисуются пути.

дополнительная документация:

Android 4.4 (уровень API 20) и ниже не поддерживает векторные чертежи. Если ваш минимальный уровень API установлен на одном из этих уровней API, Vector Asset Studio также направляет Gradle для создания растровых изображений вектора, отображаемого для обратной совместимости. Вы можете обратиться к вектору активы как Drawable в коде Java или @drawable в XML-коде; при запуске приложения соответствующее векторное или растровое изображение отображается автоматически в зависимости от уровня API.


Edit: что-то странное происходит. Вот мои результаты в эмуляторе SDK версии 23 (Lollipop+ test device is dead right now...):

Good bells on 6.x

и в версии эмулятора SDK 21:

Crappy bells on 5.x

AppCompat 23.2 представляет векторные чертежи для всех устройств под управлением Android 2.1 и выше. Изображения масштабируются правильно, независимо от ширины / высоты, указанной в XML-файле векторного чертежа. К сожалению, эта реализация не используется в API уровня 21 и выше (в пользу собственной реализации).

хорошей новостью является то, что мы можем заставить AppCompat использовать его реализацию на уровнях API 21 и 22. Плохая новость заключается в том, что мы должны использовать отражение, чтобы сделать этот.

прежде всего, убедитесь, что вы используете последнюю версию AppCompat, и что вы включили новую векторную реализацию:

android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

dependencies {
    compile 'com.android.support:appcompat-v7:23.2.0'
}

затем вызов useCompatVectorIfNeeded(); в onCreate вашего приложения ():

private void useCompatVectorIfNeeded() {
    int sdkInt = Build.VERSION.SDK_INT;
    if (sdkInt == 21 || sdkInt == 22) { //vector drawables scale correctly in API level 23
        try {
            AppCompatDrawableManager drawableManager = AppCompatDrawableManager.get();
            Class<?> inflateDelegateClass = Class.forName("android.support.v7.widget.AppCompatDrawableManager$InflateDelegate");
            Class<?> vdcInflateDelegateClass = Class.forName("android.support.v7.widget.AppCompatDrawableManager$VdcInflateDelegate");

            Constructor<?> constructor = vdcInflateDelegateClass.getDeclaredConstructor();
            constructor.setAccessible(true);
            Object vdcInflateDelegate = constructor.newInstance();

            Class<?> args[] = {String.class, inflateDelegateClass};
            Method addDelegate = AppCompatDrawableManager.class.getDeclaredMethod("addDelegate", args);
            addDelegate.setAccessible(true);
            addDelegate.invoke(drawableManager, "vector", vdcInflateDelegate);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

наконец, убедитесь, что вы используете app:srcCompat вместо android:src чтобы установить изображение вашего ImageView:

<ImageView
    android:layout_width="400dp"
    android:layout_height="400dp"
    app:srcCompat="@drawable/icon_bell"/>

ваши векторные чертежи теперь должны масштабироваться правильно!

1) Почему существует спецификация ширины/высоты в векторе drawable? Я думал, что весь смысл в том, что они масштабируются вверх и вниз без потерь, делая ширину и высоту бессмысленными в ее определении?

Это просто размер вектора по умолчанию в случае, если вы не определяете его в виде макета. (т. е. вы используете содержимое обертки для высоты и ширина вашего imageview)

2) Можно ли использовать один вектор, который работает как A 24dp drawable на TextView, а также большой ширины изображения рядом с экраном?

Да, это возможно, и у меня не было никаких проблем с изменением размера как пока работающее устройство использует леденец или выше. В предыдущих API, вектор преобразуется в pngs для разных размеров экрана, когда вы создаете приложение.

3) Как эффективно использовать атрибуты width/height и в чем разница с viewportWidth/Height?

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

Я стараюсь должен из этих способов, но, к сожалению, ни один из них не работал. Я стараюсь fitXY на ImageView Я стараюсь использовать app:srcCompat но даже не может использовать его. но я нашел хитрый способ:

установите Drawable в background вашего ImageView.

но точка этого пути-это размеры представлений. если ваш ImageView имеет неправильные размеры, drawable получает растяжку. вы должны управлять им в версиях pre-lollipop или использовать некоторые представления PercentRelativeLayout.

надеюсь, что это полезный.

первый: импорт svg в drawble : ((https://www.learn2crack.com/2016/02/android-studio-svg.html))

1-Щелкните правой кнопкой мыши на папке drawable выберите New - > Vector Asset

enter image description here

2-вектор Asset Studio предоставляет вам возможность выбрать встроенный Значки материалов или ваш собственный локальный файл svg. Вы можете переопределить размер по умолчанию если необходимый.

enter image description here

второй :если вы хотите поддержку от Android API 7+ , Вы должны использовать библиотеку поддержки Android acording ((https://stackoverflow.com/a/44713221/1140304))

1 - добавить

vectorDrawables.useSupportLibrary = true

в сборку.файл gradle.

2-Используйте пространство имен в макете, который имеет imageView:

xmlns:app="http://schemas.android.com/apk/res-auto"

третий: установите imageView с помощью android: scaleType= "fitXY" и использовать приложение:srcCompat

 <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        app:srcCompat="@drawable/ic_menu" />

в-четвертых :если вы хотите установить svg в java-коде, вы должны добавить строку ниже oncreate methoed

 @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

Я решаю свою проблему просто изменить размер векторного изображения. С самого начала это был ресурс типа:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="300"
    android:viewportWidth="300">

и я изменил его на 150dp (размер ImageView в макете с этим векторным ресурсом), например:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="150dp"
    android:height="150dp"
    android:viewportHeight="300"
    android:viewportWidth="300">

это работает для меня.

Comments

    Ничего не найдено.