下面列出了怎么用android.content.res.Resources.Theme的API类实例代码及写法,或者点击链接到github查看源代码。
private static int inferValueTypeOfKeyframe(Resources res, Theme theme, AttributeSet attrs) {
int valueType;
TypedArray a;
if (theme != null) {
a = theme.obtainStyledAttributes(attrs, R.styleable.Keyframe, 0, 0);
} else {
a = res.obtainAttributes(attrs, R.styleable.Keyframe);
}
TypedValue keyframeValue = a.peekValue(R.styleable.Keyframe_value);
boolean hasValue = (keyframeValue != null);
// When no value type is provided, check whether it's a color type first.
// If not, fall back to default value type (i.e. float type).
if (hasValue && isColorType(keyframeValue.type)) {
valueType = VALUE_TYPE_COLOR;
} else {
valueType = VALUE_TYPE_FLOAT;
}
a.recycle();
return valueType;
}
/**
* Creates a ColorStateList from an XML document using given a set of
* {@link Resources} and a {@link Theme}.
*
* @param r Resources against which the ColorStateList should be inflated.
* @param parser Parser for the XML document defining the ColorStateList.
* @param theme Optional theme to apply to the color state list, may be
* {@code null}.
* @return A new color state list.
*/
@NonNull
public static ColorStateList createFromXml(@NonNull Resources r, @NonNull XmlPullParser parser,
@Nullable Theme theme) throws XmlPullParserException, IOException {
final AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
// Seek parser to start tag.
}
if (type != XmlPullParser.START_TAG) {
throw new XmlPullParserException("No start tag found");
}
return createFromXmlInner(r, parser, attrs, theme);
}
private void updateLayerFromTypedArray(Theme theme, TypedValue[] extracted, ChildDrawable layer, TypedArray a) {
final LayerState state = mLayerState;
// Account for any configuration changes.
state.mChildrenChangingConfigurations |= TypedArrayCompat.getChangingConfigurations(a);
// Extract the theme attributes, if any.
layer.mThemeAttrs = TypedArrayCompat.extractThemeAttrs(a);
layer.mInsetL = getDimensionPixelOffset(theme, a, extracted, R.styleable.LayerDrawableItem_android_left, layer.mInsetL);
layer.mInsetT = getDimensionPixelOffset(theme, a, extracted, R.styleable.LayerDrawableItem_android_top, layer.mInsetT);
layer.mInsetR = getDimensionPixelOffset(theme, a, extracted, R.styleable.LayerDrawableItem_android_right, layer.mInsetR);
layer.mInsetB = getDimensionPixelOffset(theme, a, extracted, R.styleable.LayerDrawableItem_android_bottom, layer.mInsetB);
layer.mId = getResourceId(theme, a, extracted, R.styleable.LayerDrawableItem_android_id, layer.mId);
final Drawable dr = TypedArrayCompat.getDrawable(theme, a, extracted, R.styleable.LayerDrawableItem_android_drawable);
if (dr != null) {
layer.mDrawable = dr;
}
}
/**
* Fill in this object based on the contents of an XML "gradient" element.
*/
private void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
@NonNull AttributeSet attrs, @Nullable Theme theme)
throws XmlPullParserException, IOException {
final TypedArray a = Resources.obtainAttributes(r, theme, attrs, R.styleable.GradientColor);
updateRootElementState(a);
mChangingConfigurations |= a.getChangingConfigurations();
a.recycle();
// Check correctness and throw exception if errors found.
validateXmlContent();
inflateChildElements(r, parser, attrs, theme);
onColorsChange();
}
private static boolean viewAttrsHasLineHeight(
@NonNull Context context,
@NonNull Theme theme,
@Nullable AttributeSet attrs,
int defStyleAttr,
int defStyleRes) {
TypedArray attributes =
theme.obtainStyledAttributes(
attrs, R.styleable.MaterialTextView, defStyleAttr, defStyleRes);
int lineHeight =
readFirstAvailableDimension(
context,
attributes,
R.styleable.MaterialTextView_android_lineHeight,
R.styleable.MaterialTextView_lineHeight);
attributes.recycle();
return lineHeight != -1;
}
@Override
public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs)
throws XmlPullParserException, IOException {
// TODO THEME Not supported yet
Theme theme = null;
final VectorDrawableState state = mVectorState;
state.mVPathRenderer = new VPathRenderer();
final TypedArray a = res.obtainAttributes(attrs, R.styleable.VectorDrawable);
updateStateFromTypedArray(a);
a.recycle();
state.mCacheDirty = true;
inflateInternal(res, parser, attrs, theme);
mTintFilter = updateTintFilter(this, mTintFilter, state.mTint, state.mTintMode);
}
@TargetApi(LOLLIPOP)
static int resolveAccentColor(Context context) {
Theme theme = context.getTheme();
// on Lollipop, grab system colorAccent attribute
// pre-Lollipop, grab AppCompat colorAccent attribute
// finally, check for custom mp_colorAccent attribute
int attr = isAtLeastL() ? android.R.attr.colorAccent : R.attr.colorAccent;
TypedArray typedArray = theme.obtainStyledAttributes(new int[] { attr, R.attr.mp_colorAccent });
int accentColor = typedArray.getColor(0, FALLBACK_COLOR);
accentColor = typedArray.getColor(1, accentColor);
typedArray.recycle();
return accentColor;
}
public void setOverrideResources(JarResources myres) {
JLog.i("clf", "setOverrideResources...myres=" + myres);
if (myres == null) {
this.myResources = null;
this.resources = null;
this.assetManager = null;
this.theme = null;
return;
}
this.myResources = myres;
JLog.i("clf", "setOverrideResources...this.myResources=" + this.myResources);
this.resources = myres.getResources();
JLog.i("clf", "setOverrideResources...this.resources=" + this.resources);
this.assetManager = myres.getAssets();
JLog.i("clf", "setOverrideResources...this.assetManager=" + this.assetManager);
Theme t = myres.getResources().newTheme();
JLog.i("clf", "setOverrideResources...t=" + t);
t.setTo(getTheme());
this.theme = t;
JLog.i("clf", "setOverrideResources...this.theme=" + this.theme);
}
public MaterialTextView(
@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(wrap(context, attrs, defStyleAttr, defStyleRes), attrs, defStyleAttr);
// Ensure we are using the correctly themed context rather than the context that was passed in.
context = getContext();
if (canApplyTextAppearanceLineHeight(context)) {
final Resources.Theme theme = context.getTheme();
if (!viewAttrsHasLineHeight(context, theme, attrs, defStyleAttr, defStyleRes)) {
int resId = findViewAppearanceResourceId(theme, attrs, defStyleAttr, defStyleRes);
if (resId != -1) {
applyLineHeightFromViewAppearance(theme, resId);
}
}
}
}
/**
* Obtains styled attributes from the theme, if available, or unstyled
* resources if the theme is null.
*/
static TypedArray obtainAttributes(Resources res, Theme theme, AttributeSet set, int[] attrs) {
if (theme == null) {
return res.obtainAttributes(set, attrs);
}
return theme.obtainStyledAttributes(set, attrs, 0, 0);
}
/**
* Получить экземпляр с цветами заданной темы
* @param theme тема
* @return объект ThemeColors
*/
public static ThemeColors getInstance(Theme theme) {
if (instance == null || currentTheme != theme) {
currentTheme = theme;
TypedValue tmp = new TypedValue();
int indexColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postIndexForeground, Color.parseColor("#4F7942"));
int overBumpLimitColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postIndexOverBumpLimit, Color.parseColor("#C41E3A"));
int numberColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postNumberForeground, Color.BLACK);
int nameColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postNameForeground, Color.BLACK);
int opColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postOpForeground, Color.parseColor("#008000"));
int sageColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postSageForeground, Color.parseColor("#993333"));
int tripColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postTripForeground, Color.parseColor("#228854"));
int subscriptionBackground = ThemeUtils.getThemeColor(tmp, theme, R.attr.subscriptionBackground, Color.parseColor("#CCCCCC"));
int quoteForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.postQuoteForeground, Color.parseColor("#789922"));
int spoilerForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.spoilerForeground, Color.BLACK);
int spoilerBackground = ThemeUtils.getThemeColor(tmp, theme, R.attr.spoilerBackground, Color.parseColor("#BBBBBB"));
int urlLinkForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.urlLinkForeground, Color.parseColor("#0000EE"));
int refererForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.refererForeground, Color.parseColor("#FF0000"));
int subjectForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.postTitleForeground, Color.BLACK);
instance = new ThemeColors(
indexColor,
overBumpLimitColor,
numberColor,
nameColor,
opColor,
sageColor,
tripColor,
subscriptionBackground,
quoteForeground,
spoilerForeground,
spoilerBackground,
urlLinkForeground,
refererForeground,
subjectForeground);
}
return instance;
}
/** @hide */
public DecelerateInterpolator(Resources res, Theme theme, AttributeSet attrs) {
TypedArray a;
if (theme != null) {
a = theme.obtainStyledAttributes(attrs, R.styleable.DecelerateInterpolator, 0, 0);
} else {
a = res.obtainAttributes(attrs, R.styleable.DecelerateInterpolator);
}
mFactor = a.getFloat(R.styleable.DecelerateInterpolator_factor, 1.0f);
setChangingConfiguration(a.getChangingConfigurations());
a.recycle();
}
/** @hide */
public AnticipateInterpolator(Resources res, Theme theme, AttributeSet attrs) {
TypedArray a;
if (theme != null) {
a = theme.obtainStyledAttributes(attrs, R.styleable.AnticipateInterpolator, 0, 0);
} else {
a = res.obtainAttributes(attrs, R.styleable.AnticipateInterpolator);
}
mTension = a.getFloat(R.styleable.AnticipateInterpolator_tension, 2.0f);
setChangingConfiguration(a.getChangingConfigurations());
a.recycle();
}
public static Drawable getThemeDrawable(Context context, int res) {
Theme theme = context.getTheme();
TypedArray a = theme.obtainStyledAttributes(new int[]{res});
Drawable result = a.getDrawable(0);
a.recycle();
return result;
}
@Override
public void applyTheme(final Theme t)
{
final TypedArray ta=t.obtainStyledAttributes(R.styleable.PreloadIconDrawable);
mBgDrawable=ta.getDrawable(R.styleable.PreloadIconDrawable_backgroundIcon);
mBgDrawable.setFilterBitmap(true);
mPaint.setStrokeWidth(ta.getDimension(R.styleable.PreloadIconDrawable_indicatorSize,0));
mRingOutset=ta.getDimensionPixelSize(R.styleable.PreloadIconDrawable_ringOutset,0);
ta.recycle();
onBoundsChange(getBounds());
invalidateSelf();
}
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.RippleDrawable);
updateStateFromTypedArray(null, a, null);
a.recycle();
// Force padding default to STACK before inflating.
setPaddingMode(PADDING_MODE_STACK);
super.inflate(r, parser, attrs, theme);
setTargetDensity(r.getDisplayMetrics());
initializeFromState();
}
public static int getThemeColor(Context context, int id) {
Theme theme = context.getTheme();
TypedArray a = theme.obtainStyledAttributes(new int[]{id});
int result = a.getColor(0, DEFAULT_COLOR);
a.recycle();
return result;
}
/** @hide */
public AccelerateInterpolator(Resources res, Theme theme, AttributeSet attrs) {
TypedArray a;
if (theme != null) {
a = theme.obtainStyledAttributes(attrs, R.styleable.AccelerateInterpolator, 0, 0);
} else {
a = res.obtainAttributes(attrs, R.styleable.AccelerateInterpolator);
}
mFactor = a.getFloat(R.styleable.AccelerateInterpolator_factor, 1.0f);
mDoubleFactor = 2 * mFactor;
setChangingConfiguration(a.getChangingConfigurations());
a.recycle();
}
/**
* Create from inside an XML document. Called on a parser positioned at a
* tag in an XML document, tries to create a ColorStateList from that tag.
*
* @throws XmlPullParserException if the current tag is not <selector>
* @return A new color state list for the current tag.
*/
@NonNull
static ColorStateList createFromXmlInner(@NonNull Resources r,
@NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
throws XmlPullParserException, IOException {
final String name = parser.getName();
if (!name.equals("selector")) {
throw new XmlPullParserException(
parser.getPositionDescription() + ": invalid color state list tag " + name);
}
final ColorStateList colorStateList = new ColorStateList();
colorStateList.inflate(r, parser, attrs, theme);
return colorStateList;
}
@Override
@TargetApi(LOLLIPOP)
public void applyTheme(Theme t) {
if (LOLLIPOP_PLUS) {
super.applyTheme(t);
}
final VectorDrawableState state = mVectorState;
if (state != null && state.mThemeAttrs != null) {
/* TODO THEME Not supported yet
final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.VectorDrawable);
try {
state.mCacheDirty = true;
updateStateFromTypedArray(a);
} catch (XmlPullParserException e) {
throw new RuntimeException(e);
} finally {
a.recycle();
}
*/
mTintFilter = updateTintFilter(this, mTintFilter, state.mTint, state.mTintMode);
}
final VPathRenderer path = state.mVPathRenderer;
if (path != null && path.canApplyTheme()) {
path.applyTheme(t);
}
}
/**
* 修改各个视图绑定的属性
*/
private void makeChange(int themeId) {
Theme curTheme = mActivity.getTheme();
for (ViewSetter setter : mElements) {
setter.setValue(curTheme, themeId);
}
}
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) throws XmlPullParserException, IOException {
super.inflate(r, parser, attrs, theme);
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.LayerDrawable);
updateStateFromTypedArray(theme, a, null);
a.recycle();
inflateLayers(r, parser, attrs, theme);
ensurePadding();
onStateChange(getState());
}
@Override
public void setValue(Theme newTheme, int themeId) {
mView.setBackgroundColor(getColor(newTheme));
// 清空AbsListView的元素
clearListViewRecyclerBin(mView);
// 清空RecyclerView
clearRecyclerViewRecyclerBin(mView);
// 修改所有子元素的相关属性
changeChildenAttrs((ViewGroup) mView, newTheme, themeId);
}
public void inflate(Resources res, AttributeSet attrs, Theme theme) {
// TODO TINT THEME Not supported yet
final TypedArray a = res.obtainAttributes(attrs,
R.styleable.VectorDrawableGroup);
updateStateFromTypedArray(a);
a.recycle();
}
private void applyTheme(Theme t) {
if (mThemeAttrs != null) {
applyRootAttrsTheme(t);
}
if (mItemsThemeAttrs != null) {
applyItemsAttrsTheme(t);
}
onColorsChange();
}
private void applyRootAttrsTheme(Theme t) {
final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.GradientColor);
// mThemeAttrs will be set to null if if there are no theme attributes in the
// typed array.
mThemeAttrs = a.extractThemeAttrs(mThemeAttrs);
// merging the attributes update inside the updateRootElementState().
updateRootElementState(a);
// Account for any configuration changes.
mChangingConfigurations |= a.getChangingConfigurations();
a.recycle();
}
public static int getColor(int colorId, Theme theme) {
Resources resources = NoHttp.getContext().getResources();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
return resources.getColor(colorId, theme);
else
return resources.getColor(colorId);
}
private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) {
if (theme != null && state.canApplyThemeCompat()) {
// If we need to apply a theme, implicitly mutate.
mVectorState = new VectorDrawableState(state);
applyTheme(theme);
} else {
mVectorState = state;
}
mTintFilter = updateTintFilter(this, mTintFilter, state.mTint, state.mTintMode);
}
public static ColorStateList getColorStateList(int colorStateId, Theme theme) {
Resources resources = NoHttp.getContext().getResources();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
return resources.getColorStateList(colorStateId, theme);
else
return resources.getColorStateList(colorStateId);
}
/**
* Returns {@link ColorStateList} for attr from the {@link Theme}
*
* @param theme {@link Theme} to get int from
* @param attr Attribute of the int
* @return {@link Drawable} for attr from the {@link Theme}
*/
@Nullable
public static Drawable getDrawable(@NonNull final Theme theme,
@AttrRes final int attr) {
final TypedArray array = theme.obtainStyledAttributes(new int[]{attr});
try {
return array.getDrawable(0);
} finally {
array.recycle();
}
}