ResourcesCompat.getDrawable () vs AppCompatResources.getDrawable()
Я немного запутался с этими двумя API.
ResourcesCompat.getDrawable (Resources res, int id, Resources.Тема тема)
возвращает объект мешочки, связанного с определенным идентификатором ресурса и стиле на заданную тему. Различные типы объектов будут возвращены в зависимости от базового ресурса - например, сплошной цвет, PNG-изображение, масштабируемое изображение и т. д.
до уровня API 21, тема не будет применяться, и этот метод просто вызывает getDrawable (int).
AppCompatResources.getDrawable (контекстный контекст, int resId)
возвращает объект катры, связанного с определенным идентификатором ресурса.
этот метод поддерживает инфляции вектор и мультипликация-вектор ресурсы на устройствах с поддержкой платформы не доступный.
вопрос
- в чем существенная разница между этими двумя классами (кроме того!--3-->вектор инфляция)?
- какой из них следует предпочесть другому и почему?
3 ответов
глядя на исходный код этих двух методов, они кажутся очень похожими. Если у вас нет направления, вы можете использовать либо одно, либо другое.
ResourceCompat.getDrawable() будем называть Resources#getDrawable(int, theme)
на APIs 21 или выше. Он также поддерживает Android APIs 4+. Это не более чем:
public Drawable getDrawable(Resources res, int id, Theme theme)
throws NotFoundException {
final int version = Build.VERSION.SDK_INT;
if (version >= 21) {
return ResourcesCompatApi21.getDrawable(res, id, theme);
} else {
return res.getDrawable(id);
}
}
где-в ResourcesCompatApi21
просто называет res.getDrawable(id, theme)
. Это означает, что это будет не разрешить рисование векторных чертежей, если устройство не поддерживает векторные чертежи. Это, однако, позволит вам перейти к теме.
между тем, изменение кода для AppCompatResources.getDrawable (контекстный контекст, int resId) в конце концов приземляется на это:
Drawable getDrawable(@NonNull Context context, @DrawableRes int resId, boolean failIfNotKnown) {
checkVectorDrawableSetup(context);
Drawable drawable = loadDrawableFromDelegates(context, resId);
if (drawable == null) {
drawable = createDrawableIfNeeded(context, resId);
}
if (drawable == null) {
drawable = ContextCompat.getDrawable(context, resId);
}
if (drawable != null) {
// Tint it if needed
drawable = tintDrawable(context, resId, failIfNotKnown, drawable);
}
if (drawable != null) {
// See if we need to 'fix' the drawable
DrawableUtils.fixDrawable(drawable);
}
return drawable;
}
таким образом, этот экземпляр попытается нарисовать ресурс, если он может, иначе он выглядит в ContextCompat
версия для получения ресурсов. Тогда он даже будет окрашивать его, если это необходимо. Однако, этот метод поддерживает только API 7+.
так что я думаю решить, если вы должны использовать либо
-
вам нужно поддерживать API 4, 5 или 6?
- Да: нет выбора, кроме как использовать
ResourcesCompat
илиContextCompat
. - нет: продолжайте идти к #2.
- Да: нет выбора, кроме как использовать
-
вам абсолютно необходимо предоставить пользовательскую тему?
- Да: нет выбора, кроме как использовать
ResourcesCompat
- Нет: Использовать
AppCompatResources
- Да: нет выбора, кроме как использовать
вот мой понимаю после некоторого теста
ContextCompat.getDrawable(@NonNull Context context, @DrawableRes int resId)
ResourcesCompat.getDrawable(@NonNull Resources res, @DrawableRes int id, @Nullable Theme theme)
AppCompatResources.getDrawable(@NonNull Context context, @DrawableRes int resId)
VectorDrawableCompat.create(@NonNull Resources res, @DrawableRes int resId, @Nullable Theme theme
первое, что вижу-это VectorDrawableCompat
и ResourcesCompat
может конкретная тема
I) без использования
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
на onCreated
класса приложения
1) для векторного изображения
-
API >= 21
-
ContextCompat
хорошо работать -
ResourcesCompat
хорошо работать -
AppCompatResources
работа ну!--47--> -
VectorDrawableCompat
хорошо работать
-
-
API
-
ContextCompat
авария -
ResourcesCompat
авария -
AppCompatResources
хорошо работать -
VectorDrawableCompat
хорошо работать
-
2) для нормального изображения
- на всех уровнях
-
ContextCompat
работа ну!--47--> -
ResourcesCompat
хорошо работать -
AppCompatResources
хорошо работать -
VectorDrawableCompat
авария
-
II) использовать
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
на onCreated
класса приложения
1) для векторного изображения
- на всех уровнях
-
ContextCompat
хорошо работать -
ResourcesCompat
хорошо работать -
AppCompatResources
работа ну!--47--> -
VectorDrawableCompat
хорошо работать
-
2) для нормального изображения
- на всех уровнях
-
ContextCompat
хорошо работать -
ResourcesCompat
хорошо работать -
AppCompatResources
хорошо работать -
VectorDrawableCompat
авария
-
ContextCompat
ResourcesCompat
, ContextCompat
и практически любой класс из support-v4, заканчивающийся на Compat
спасает вас от написания if (Build.VERSION.SDK_INT >= X)
проверяет везде. Вот и все. Например, вместо
final Drawable d;
if (Build.VERSION.SDK_INT < 21) {
// Old method, drawables cannot contain theme references.
d = context.getResources().getDrawable(R.drawable.some_image);
} else {
// Drawables on API 21 can contain theme attribute references.
// Context#getDrawable only exists since API 21.
d = context.getDrawable(R.drawable.some_image);
}
можно писать
final Drawable d = ContextCompat.getDrawable(context, R.drawable.some_image);
применяются ограничения, описанные в комментариях, например
// This line is effectively equivalent to the above.
ResourcesCompat.getDrawable(context.getResources(), R.drawable.some_image, context.getTheme());
фактически не применяет атрибуты темы перед Lollipop (об этом говорится в документации). Но тебе не обязательно писать, если проверяет, и ваш код не аварийно завершает работу на старых устройствах, потому что вы фактически не используете новые API.
AppCompatResources
AppCompatResources
С другой стороны, фактически поможет вам принести новые функции на старые платформы (векторы поддержки, ссылки на темы в списках состояний цвета).
какой из них следует предпочесть другому и почему?
использовать AppCompatResources
чтобы получить согласованные результаты с остальной частью библиотеки appcompat-v7. Вы получить:
-
getColorStateList
который может разрешать цвета со ссылками на атрибуты темы (например,android:alpha="?android:disabledAlpha"
), -
getDrawable
который поддерживает раздувание векторов на всех платформах, и эти векторные чертежи также понимают ссылки на атрибуты темы (например,android:tint="?colorControlNormal"
), - AppCompat-V7 drawables и цвета, такие как флажки или переключатели, будут иметь правильные цвета, определенные поставляемой темой контекста,
- если вышеуказанное не применяется, то оно падает назад к
ContextCompat
в любом случае.