下面列出了android.content.res.Resources.Theme#obtainStyledAttributes() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@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;
}
@SuppressWarnings("deprecation")
@Override
public void setValue(Theme newTheme, int themeId) {
if ( mView == null ) {
return ;
}
TypedArray a = newTheme.obtainStyledAttributes(themeId,
new int[] { mAttrResId });
int attributeResourceId = a.getResourceId(0, 0);
Drawable drawable = mView.getResources().getDrawable(
attributeResourceId);
a.recycle();
mView.setBackgroundDrawable(drawable);
}
/** @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();
}
/** @hide */
public PathInterpolator(Resources res, Theme theme, AttributeSet attrs) {
TypedArray a;
if (theme != null) {
a = theme.obtainStyledAttributes(attrs, R.styleable.PathInterpolator, 0, 0);
} else {
a = res.obtainAttributes(attrs, R.styleable.PathInterpolator);
}
parseInterpolatorFromTypeArray(a);
setChangingConfiguration(a.getChangingConfigurations());
a.recycle();
}
/**
* 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();
}
}
/** @hide */
public CycleInterpolator(Resources resources, Theme theme, AttributeSet attrs) {
TypedArray a;
if (theme != null) {
a = theme.obtainStyledAttributes(attrs, R.styleable.CycleInterpolator, 0, 0);
} else {
a = resources.obtainAttributes(attrs, R.styleable.CycleInterpolator);
}
mCycles = a.getFloat(R.styleable.CycleInterpolator_cycles, 1.0f);
setChangingConfiguration(a.getChangingConfigurations());
a.recycle();
}
/** @hide */
public OvershootInterpolator(Resources res, Theme theme, AttributeSet attrs) {
TypedArray a;
if (theme != null) {
a = theme.obtainStyledAttributes(attrs, R.styleable.OvershootInterpolator, 0, 0);
} else {
a = res.obtainAttributes(attrs, R.styleable.OvershootInterpolator);
}
mTension = a.getFloat(R.styleable.OvershootInterpolator_tension, 2.0f);
setChangingConfiguration(a.getChangingConfigurations());
a.recycle();
}
/**
* 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 ColorStateList} for attr from the {@link Theme}
*/
@Nullable
public static ColorStateList getColorStateList(@NonNull final Theme theme,
@AttrRes final int attr) {
final TypedArray array = theme.obtainStyledAttributes(new int[]{attr});
try {
return array.getColorStateList(0);
} finally {
array.recycle();
}
}
/**
* 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);
}
/**
* Returns color for attr from the {@link Theme}
*
* @param theme {@link Theme} to get int from
* @param attr Attribute of the int
* @return color for attr from the {@link Theme}
*/
@ColorInt
public static int getColor(@NonNull final Theme theme, @AttrRes final int attr) {
final TypedArray array = theme.obtainStyledAttributes(new int[]{attr});
try {
return array.getColor(0, Color.TRANSPARENT);
} finally {
array.recycle();
}
}
@SuppressWarnings("deprecation")
@Override
public void setValue(Theme newTheme, int themeId) {
if ( mView == null ) {
return ;
}
TypedArray a = newTheme.obtainStyledAttributes(themeId,
new int[] { mAttrResId });
int attributeResourceId = a.getResourceId(0, 0);
Drawable drawable = mView.getResources().getDrawable(
attributeResourceId);
a.recycle();
mView.setBackgroundDrawable(drawable);
}
public static boolean getThemeDark(Context context, int id) {
Theme theme = context.getTheme();
TypedArray a = theme.obtainStyledAttributes(new int[]{id});
boolean result = a.getBoolean(0, false);
a.recycle();
return result;
}
public static boolean getThemeDark(Context context, int id) {
Theme theme = context.getTheme();
TypedArray a = theme.obtainStyledAttributes(new int[]{id});
boolean result = a.getBoolean(0, false);
a.recycle();
return result;
}
public void applyPreloaderTheme(Theme t) {
TypedArray ta = t.obtainStyledAttributes(R.styleable.PreloadIconDrawable);
mBgDrawable = ta.getDrawable(R.styleable.PreloadIconDrawable_background);
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();
}
private void applyLineHeightFromViewAppearance(@NonNull Theme theme, int resId) {
TypedArray attributes = theme.obtainStyledAttributes(resId, R.styleable.MaterialTextAppearance);
int lineHeight =
readFirstAvailableDimension(
getContext(),
attributes,
R.styleable.MaterialTextAppearance_android_lineHeight,
R.styleable.MaterialTextAppearance_lineHeight);
attributes.recycle();
if (lineHeight >= 0) {
setLineHeight(lineHeight);
}
}
/**
* Applies the font and all related custom properties found in the attributes of the given
* AttributeSet or the default style to the given target. Typically, the AttributeSet consists
* of the attributes contained in the xml tag that defined the target. The target can be any
* TextView or subclass thereof. The read properties will be stored in an {@link ExtraFontData}
* instance stored as a tag with id {@link R.id#flFontsExtraData} in the target view. If an
* instance was already set as a tag in the target view, it will be reused. All encountered
* properties are overridden. The properties in the data holder can be changed later, but it
* will depend on the nature of the property whether or not this change will take effect.
* Properties that are applied at initialization will not be applied when changed and properties
* that are applied during the render cycle will be applied when changed.
*
* @param target A TextView, or any UI element that inherits from TextView.
* @param attrs The attributes from the xml tag that defined the target.
* @param defStyle The style that is applied to the target element. This may either be an
* attribute resource, whose value will be retrieved from the current theme, or an
* explicit style resource.
*/
public static void applyFont(TextView target, AttributeSet attrs, int defStyle) {
if (target == null || target.isInEditMode()) {
return;
}
ExtraFontData data = getFontData(target);
// First get the font attribute from the textAppearance:
Theme theme = target.getContext().getTheme();
// Get the text appearance that's currently in use
TypedArray a = theme.obtainStyledAttributes(attrs,
new int[] {android.R.attr.textAppearance}, defStyle, 0);
int textAppearanceStyle = -1;
try {
textAppearanceStyle = a.getResourceId(0, -1);
} finally {
a.recycle();
}
// Get the font and style defined in the text appearance
TypedArray appearance = null;
if (textAppearanceStyle != -1) {
appearance = theme.obtainStyledAttributes(textAppearanceStyle,
R.styleable.Fonts);
}
getAttributes(appearance, data);
// Then get the font attribute from the FontTextView itself:
a = theme.obtainStyledAttributes(attrs, R.styleable.Fonts, defStyle, 0);
getAttributes(a, data);
// Now we have the font, apply it
if (data.font != null) {
getInstance().setTypeface(target, data.font, data.style);
}
}
private static int findViewAppearanceResourceId(
@NonNull Theme theme, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
TypedArray attributes =
theme.obtainStyledAttributes(
attrs, R.styleable.MaterialTextView, defStyleAttr, defStyleRes);
int appearanceAttrId =
attributes.getResourceId(R.styleable.MaterialTextView_android_textAppearance, -1);
attributes.recycle();
return appearanceAttrId;
}
private static PropertyValuesHolder[] loadValues(Resources res, Theme theme,
XmlPullParser parser, AttributeSet attrs) throws XmlPullParserException, IOException {
ArrayList<PropertyValuesHolder> values = null;
int type;
while ((type = parser.getEventType()) != XmlPullParser.END_TAG &&
type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
parser.next();
continue;
}
String name = parser.getName();
if (name.equals("propertyValuesHolder")) {
TypedArray a;
if (theme != null) {
a = theme.obtainStyledAttributes(attrs, R.styleable.PropertyValuesHolder, 0, 0);
} else {
a = res.obtainAttributes(attrs, R.styleable.PropertyValuesHolder);
}
String propertyName = a.getString(R.styleable.PropertyValuesHolder_propertyName);
int valueType = a.getInt(R.styleable.PropertyValuesHolder_valueType,
VALUE_TYPE_UNDEFINED);
PropertyValuesHolder pvh = loadPvh(res, theme, parser, propertyName, valueType);
if (pvh == null) {
pvh = getPVH(a, valueType,
R.styleable.PropertyValuesHolder_valueFrom,
R.styleable.PropertyValuesHolder_valueTo, propertyName);
}
if (pvh != null) {
if (values == null) {
values = new ArrayList<PropertyValuesHolder>();
}
values.add(pvh);
}
a.recycle();
}
parser.next();
}
PropertyValuesHolder[] valuesArray = null;
if (values != null) {
int count = values.size();
valuesArray = new PropertyValuesHolder[count];
for (int i = 0; i < count; ++i) {
valuesArray[i] = values.get(i);
}
}
return valuesArray;
}
private static Keyframe loadKeyframe(Resources res, Theme theme, AttributeSet attrs,
int valueType)
throws XmlPullParserException, IOException {
TypedArray a;
if (theme != null) {
a = theme.obtainStyledAttributes(attrs, R.styleable.Keyframe, 0, 0);
} else {
a = res.obtainAttributes(attrs, R.styleable.Keyframe);
}
Keyframe keyframe = null;
float fraction = a.getFloat(R.styleable.Keyframe_fraction, -1);
TypedValue keyframeValue = a.peekValue(R.styleable.Keyframe_value);
boolean hasValue = (keyframeValue != null);
if (valueType == VALUE_TYPE_UNDEFINED) {
// 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;
}
}
if (hasValue) {
switch (valueType) {
case VALUE_TYPE_FLOAT:
float value = a.getFloat(R.styleable.Keyframe_value, 0);
keyframe = Keyframe.ofFloat(fraction, value);
break;
case VALUE_TYPE_COLOR:
case VALUE_TYPE_INT:
int intValue = a.getInt(R.styleable.Keyframe_value, 0);
keyframe = Keyframe.ofInt(fraction, intValue);
break;
}
} else {
keyframe = (valueType == VALUE_TYPE_FLOAT) ? Keyframe.ofFloat(fraction) :
Keyframe.ofInt(fraction);
}
final int resID = a.getResourceId(R.styleable.Keyframe_interpolator, 0);
if (resID > 0) {
final Interpolator interpolator = AnimationUtils.loadInterpolator(res, theme, resID);
keyframe.setInterpolator(interpolator);
}
a.recycle();
return keyframe;
}
/**
* Creates a new animation whose parameters come from the specified context
* and attributes set.
*
* @param res The resources
* @param attrs The set of attributes holding the animation parameters
* @param anim Null if this is a ValueAnimator, otherwise this is an
* ObjectAnimator
*/
private static ValueAnimator loadAnimator(Resources res, Theme theme,
AttributeSet attrs, ValueAnimator anim, float pathErrorScale)
throws NotFoundException {
TypedArray arrayAnimator = null;
TypedArray arrayObjectAnimator = null;
if (theme != null) {
arrayAnimator = theme.obtainStyledAttributes(attrs, R.styleable.Animator, 0, 0);
} else {
arrayAnimator = res.obtainAttributes(attrs, R.styleable.Animator);
}
// If anim is not null, then it is an object animator.
if (anim != null) {
if (theme != null) {
arrayObjectAnimator = theme.obtainStyledAttributes(attrs,
R.styleable.PropertyAnimator, 0, 0);
} else {
arrayObjectAnimator = res.obtainAttributes(attrs, R.styleable.PropertyAnimator);
}
anim.appendChangingConfigurations(arrayObjectAnimator.getChangingConfigurations());
}
if (anim == null) {
anim = new ValueAnimator();
}
anim.appendChangingConfigurations(arrayAnimator.getChangingConfigurations());
parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator, pathErrorScale);
final int resID = arrayAnimator.getResourceId(R.styleable.Animator_interpolator, 0);
if (resID > 0) {
final Interpolator interpolator = AnimationUtils.loadInterpolator(res, theme, resID);
if (interpolator instanceof BaseInterpolator) {
anim.appendChangingConfigurations(
((BaseInterpolator) interpolator).getChangingConfiguration());
}
anim.setInterpolator(interpolator);
}
arrayAnimator.recycle();
if (arrayObjectAnimator != null) {
arrayObjectAnimator.recycle();
}
return anim;
}