Почему мой вектор не рисуется масштабирование, как ожидалось?
Я пытаюсь использовать векторные чертежи в моем приложении для 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):

изменение ширины и высоты в определении вектора 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. Растрированные изображения не создаются.
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...):
и в версии эмулятора SDK 21:
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
2-вектор Asset Studio предоставляет вам возможность выбрать встроенный Значки материалов или ваш собственный локальный файл svg. Вы можете переопределить размер по умолчанию если необходимый.
второй :если вы хотите поддержку от 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