/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.litho;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.support.annotation.ArrayRes;
import android.support.annotation.AttrRes;
import android.support.annotation.BoolRes;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.IntegerRes;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
public class ResourceResolver {
private ComponentContext mContext;
private Resources mResources;
private Resources.Theme mTheme;
private ResourceCache mResourceCache;
// Use for *Attr methods to retrieve attributes without needing to
// allocate a new int[] for each call.
private final int[] mAttrs = new int[1];
public final void init(ComponentContext context, ResourceCache resourceCache) {
mContext = context;
mResources = context.getResources();
mTheme = context.getTheme();
mResourceCache = resourceCache;
}
protected final int dipsToPixels(float dips) {
final float scale = mResources.getDisplayMetrics().density;
return FastMath.round(dips * scale);
}
final int dipsToPixels(int dips) {
return dipsToPixels((float) dips);
}
protected final int sipsToPixels(float dips) {
final float scale = mResources.getDisplayMetrics().scaledDensity;
return FastMath.round(dips * scale);
}
public final int sipsToPixels(int dips) {
return dipsToPixels((float) dips);
}
protected final String resolveStringRes(@StringRes int resId) {
if (resId != 0) {
String cached = mResourceCache.get(resId);
if (cached != null) {
return cached;
}
String result = mResources.getString(resId);
mResourceCache.put(resId, result);
return result;
}
return null;
}
protected final String resolveStringRes(@StringRes int resId, Object... formatArgs) {
return resId != 0 ? mResources.getString(resId, formatArgs) : null;
}
private final String[] resolveStringArrayRes(@ArrayRes int resId) {
if (resId != 0) {
String[] cached = mResourceCache.get(resId);
if (cached != null) {
return cached;
}
String[] result = mResources.getStringArray(resId);
mResourceCache.put(resId, result);
return result;
}
return null;
}
protected final int resolveIntRes(@IntegerRes int resId) {
if (resId != 0) {
Integer cached = mResourceCache.get(resId);
if (cached != null) {
return cached;
}
int result = mResources.getInteger(resId);
mResourceCache.put(resId, result);
return result;
}
return 0;
}
private final int[] resolveIntArrayRes(@ArrayRes int resId) {
if (resId != 0) {
int[] cached = mResourceCache.get(resId);
if (cached != null) {
return cached;
}
int[] result = mResources.getIntArray(resId);
mResourceCache.put(resId, result);
return result;
}
return null;
}
protected final boolean resolveBoolRes(@BoolRes int resId) {
if (resId != 0) {
Boolean cached = mResourceCache.get(resId);
if (cached != null) {
return cached;
}
boolean result = mResources.getBoolean(resId);
mResourceCache.put(resId, result);
return result;
}
return false;
}
protected final int resolveColorRes(@ColorRes int resId) {
if (resId != 0) {
Integer cached = mResourceCache.get(resId);
if (cached != null) {
return cached;
}
int result = mResources.getColor(resId);
mResourceCache.put(resId, result);
return result;
}
return 0;
}
protected final int resolveDimenSizeRes(@DimenRes int resId) {
if (resId != 0) {
Integer cached = mResourceCache.get(resId);
if (cached != null) {
return cached;
}
int result = mResources.getDimensionPixelSize(resId);
mResourceCache.put(resId, result);
return result;
}
return 0;
}
protected final int resolveDimenOffsetRes(@DimenRes int resId) {
if (resId != 0) {
Integer cached = mResourceCache.get(resId);
if (cached != null) {
return cached;
}
int result = mResources.getDimensionPixelOffset(resId);
mResourceCache.put(resId, result);
return result;
}
return 0;
}
protected final float resolveFloatRes(@DimenRes int resId) {
if (resId != 0) {
Float cached = mResourceCache.get(resId);
if (cached != null) {
return cached;
}
float result = mResources.getDimension(resId);
mResourceCache.put(resId, result);
return result;
}
return 0;
}
@Nullable
protected final Drawable resolveDrawableRes(@DrawableRes int resId) {
if (resId == 0) {
return null;
}
return mResources.getDrawable(resId);
}
protected final String resolveStringAttr(@AttrRes int attrResId, @StringRes int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mTheme.obtainStyledAttributes(mAttrs);
try {
String result = a.getString(0);
if (result == null) {
result = resolveStringRes(defResId);
}
return result;
} finally {
a.recycle();
}
}
public final String[] resolveStringArrayAttr(@AttrRes int attrResId, @ArrayRes int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mContext.getTheme().obtainStyledAttributes(mAttrs);
try {
return resolveStringArrayRes(a.getResourceId(0, defResId));
} finally {
a.recycle();
}
}
protected final int resolveIntAttr(@AttrRes int attrResId, @IntegerRes int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mTheme.obtainStyledAttributes(mAttrs);
try {
return a.getInt(0, resolveIntRes(defResId));
} finally {
a.recycle();
}
}
public final int[] resolveIntArrayAttr(@AttrRes int attrResId, @ArrayRes int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mContext.getTheme().obtainStyledAttributes(mAttrs);
try {
return resolveIntArrayRes(a.getResourceId(0, defResId));
} finally {
a.recycle();
}
}
protected final boolean resolveBoolAttr(@AttrRes int attrResId, @BoolRes int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mTheme.obtainStyledAttributes(mAttrs);
try {
return a.getBoolean(0, resolveBoolRes(defResId));
} finally {
a.recycle();
}
}
protected final int resolveColorAttr(@AttrRes int attrResId, @ColorRes int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mTheme.obtainStyledAttributes(mAttrs);
try {
return a.getColor(0, resolveColorRes(defResId));
} finally {
a.recycle();
}
}
protected final int resolveDimenSizeAttr(@AttrRes int attrResId, @DimenRes int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mTheme.obtainStyledAttributes(mAttrs);
try {
return a.getDimensionPixelSize(0, resolveDimenSizeRes(defResId));
} finally {
a.recycle();
}
}
protected final int resolveDimenOffsetAttr(@AttrRes int attrResId, @DimenRes int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mTheme.obtainStyledAttributes(mAttrs);
try {
return a.getDimensionPixelOffset(0, resolveDimenOffsetRes(defResId));
} finally {
a.recycle();
}
}
protected final float resolveFloatAttr(@AttrRes int attrResId, @DimenRes int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mTheme.obtainStyledAttributes(mAttrs);
try {
return a.getDimension(0, resolveFloatRes(defResId));
} finally {
a.recycle();
}
}
@Nullable
protected final Drawable resolveDrawableAttr(
@AttrRes int attrResId,
@DrawableRes int defResId) {
if (attrResId == 0) {
return null;
}
mAttrs[0] = attrResId;
TypedArray a = mTheme.obtainStyledAttributes(mAttrs);
try {
return resolveDrawableRes(a.getResourceId(0, defResId));
} finally {
a.recycle();
}
}
final int resolveResIdAttr(@AttrRes int attrResId, int defResId) {
mAttrs[0] = attrResId;
TypedArray a = mTheme.obtainStyledAttributes(mAttrs);
try {
return a.getResourceId(0, defResId);
} finally {
a.recycle();
}
}
protected void release() {
internalRelease();
}
void internalRelease() {
mContext = null;
mResources = null;
mTheme = null;
mResourceCache = null;
}
}