Theme、Style、attr、declare-styleable
Theme或者Style中(或者说Android中其他xml资源使用的属性)的属性都是一样的,首先都需要定义
Theme是Style的子集,定义Theme和定义一般style形式上是一样的,只是内容略有不同。如果Theme的属性有些是针对Window的有些是针对View的,而一般的style中的属性是只针对View的。
reference数据类型,一般是用于指向某个style,也可以指向某个类型的数据,如color,string等使用示例:
- @style/Widget.Button
在定义或者声明attr时,并没有指明这些属性是属于谁的,所以谁都能用。系统的widget一般都在java文件中使用了注解,TextView的如下:
* * XML attributes*
* See {@link android.R.styleable#TextView TextView Attributes},* {@link android.R.styleable#View View Attributes}** @attr ref android.R.styleable#TextView_text* @attr ref android.R.styleable#TextView_bufferType* @attr ref android.R.styleable#TextView_hint* @attr ref android.R.styleable#TextView_textColor* @attr ref android.R.styleable#TextView_textColorHighlight* @attr ref android.R.styleable#TextView_textColorHint* @attr ref android.R.styleable#TextView_textAppearance* @attr ref android.R.styleable#TextView_textColorLink* @attr ref android.R.styleable#TextView_textSize* @attr ref android.R.styleable#TextView_textScaleX* @attr ref android.R.styleable#TextView_fontFamily* @attr ref android.R.styleable#TextView_typeface* @attr ref android.R.styleable#TextView_textStyle* @attr ref android.R.styleable#TextView_cursorVisible* @attr ref android.R.styleable#TextView_maxLines* @attr ref android.R.styleable#TextView_maxHeight* @attr ref android.R.styleable#TextView_lines* @attr ref android.R.styleable#TextView_height* @attr ref android.R.styleable#TextView_minLines* @attr ref android.R.styleable#TextView_minHeight* @attr ref android.R.styleable#TextView_maxEms* @attr ref android.R.styleable#TextView_maxWidth* @attr ref android.R.styleable#TextView_ems* @attr ref android.R.styleable#TextView_width* @attr ref android.R.styleable#TextView_minEms* @attr ref android.R.styleable#TextView_minWidth* @attr ref android.R.styleable#TextView_gravity* @attr ref android.R.styleable#TextView_scrollHorizontally* @attr ref android.R.styleable#TextView_password* @attr ref android.R.styleable#TextView_singleLine* @attr ref android.R.styleable#TextView_selectAllOnFocus* @attr ref android.R.styleable#TextView_includeFontPadding* @attr ref android.R.styleable#TextView_maxLength* @attr ref android.R.styleable#TextView_shadowColor* @attr ref android.R.styleable#TextView_shadowDx* @attr ref android.R.styleable#TextView_shadowDy* @attr ref android.R.styleable#TextView_shadowRadius* @attr ref android.R.styleable#TextView_autoLink* @attr ref android.R.styleable#TextView_linksClickable* @attr ref android.R.styleable#TextView_numeric* @attr ref android.R.styleable#TextView_digits* @attr ref android.R.styleable#TextView_phoneNumber* @attr ref android.R.styleable#TextView_inputMethod* @attr ref android.R.styleable#TextView_capitalize* @attr ref android.R.styleable#TextView_autoText* @attr ref android.R.styleable#TextView_editable* @attr ref android.R.styleable#TextView_freezesText* @attr ref android.R.styleable#TextView_ellipsize* @attr ref android.R.styleable#TextView_drawableTop* @attr ref android.R.styleable#TextView_drawableBottom* @attr ref android.R.styleable#TextView_drawableRight* @attr ref android.R.styleable#TextView_drawableLeft* @attr ref android.R.styleable#TextView_drawableStart* @attr ref android.R.styleable#TextView_drawableEnd* @attr ref android.R.styleable#TextView_drawablePadding* @attr ref android.R.styleable#TextView_drawableTint* @attr ref android.R.styleable#TextView_drawableTintMode* @attr ref android.R.styleable#TextView_lineSpacingExtra* @attr ref android.R.styleable#TextView_lineSpacingMultiplier* @attr ref android.R.styleable#TextView_marqueeRepeatLimit* @attr ref android.R.styleable#TextView_inputType* @attr ref android.R.styleable#TextView_imeOptions* @attr ref android.R.styleable#TextView_privateImeOptions* @attr ref android.R.styleable#TextView_imeActionLabel* @attr ref android.R.styleable#TextView_imeActionId* @attr ref android.R.styleable#TextView_editorExtras* @attr ref android.R.styleable#TextView_elegantTextHeight* @attr ref android.R.styleable#TextView_letterSpacing* @attr ref android.R.styleable#TextView_fontFeatureSettings* @attr ref android.R.styleable#TextView_breakStrategy* @attr ref android.R.styleable#TextView_hyphenationFrequency* @attr ref android.R.styleable#TextView_autoSizeTextType* @attr ref android.R.styleable#TextView_autoSizeMinTextSize* @attr ref android.R.styleable#TextView_autoSizeMaxTextSize* @attr ref android.R.styleable#TextView_autoSizeStepGranularity* @attr ref android.R.styleable#TextView_autoSizePresetSizes
这样在编写layout文件使用到TextView时编译器就能自动检查哪些属性能用哪些不能用。
Window的属性基本都在R.styleable.Window中声明了。
关于xmlns命名空间,xml标准原意是赋予命名空间一个惟一的名称。不过,很多公司常常会作为指针来使用命名空间指向实际存在的网页,这个网页包含关于命名空间的信息。而Android中定义这个命名空间的标准是在使用到自定义View的xml布局文件中需要加入在引用Library的第三方View时,我们需要在XML布局文件头部添加xmlns:app="http://schemas.android.com/apk/res-auto"或者xmlns:app="http://schemas.android.com/apk/res/包名"。所以xmlns:android="http://schemas.android.com/apk/res/android"是因为系统属性都定义在package name为"andrioid"的apk(framework_res.apk)中。
系统的xml资源除了兼容包中的,其他都在frameworks/base/core/res中,attr在res/values中的attrs.xml,attrs_manifest.xml,而style在styles.xml,styles_device_defaults.xml,styles_material.xml等文件中。Theme在themes.xml,themes_device_defaults.xml,themes_material.xml等。
frameworks/base/core/res中定义style和Theme都是不带android这个xmlns前缀的,但是看到v7包中有些Theme部分属性会加,查过这些属性在frameworks/base/core/res中是没有加的,有时候使用的时确实必须要加上才能用,不知道为什么,有知道的留言告诉一下。
还拿TextView来分析,因为相对比较简单。在TextView构造函数中,首先取TextView绑定的Context的theme中TextView感兴趣的属性,然后再取Layout文件中属性,如果前者和后者有相同的,则后者覆盖前者。TextView构造方法中,跟提取属性相关的代码如下:
final Resources.Theme theme = context.getTheme();/** Look the appearance up without checking first if it exists because* almost every TextView has one and it greatly simplifies the logic* to be able to parse the appearance first and then let specific tags* for this View override it.*/TypedArray a = theme.obtainStyledAttributes(attrs,com.android.internal.R.styleable.TextViewAppearance, defStyleAttr, defStyleRes);//TextViewAppearance只声明了一个属性,textAppearance,format="reference"
//然后在Theme中加入与Text相关的属性时,把所有属性集合到一个style中,使textAppearance指向
//该styleTypedArray appearance = null;int ap = a.getResourceId(com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);a.recycle();//提取该textAppearance指向的styleif (ap != -1) {
//从textAppearance指向的style中取出TextAppearance声明过的属性。下面会从attrs中取出布局文件
//中在R.styleable.TextView声明过的属性。所以由此可看出,有些属性可以在Theme中声明,
//有些必须要在layout文件中声明,在Theme声明了也没用。而且在Theme怎么声明也要看代码中怎么写,
//在TextView中,如果想在Theme中声明textColor这个属性,需要写在一个style,然后使用
//textAppearance指向它。(也许单独在Theme中声明textColor也行,一样会写如attrs中,然后在下一阶段取出)appearance = theme.obtainStyledAttributes(ap, com.android.internal.R.styleable.TextAppearance);}if (appearance != null) {int n = appearance.getIndexCount();for (int i = 0; i < n; i++) {int attr = appearance.getIndex(i);switch (attr) {case com.android.internal.R.styleable.TextAppearance_textColorHighlight:textColorHighlight = appearance.getColor(attr, textColorHighlight);break;case com.android.internal.R.styleable.TextAppearance_textColor:textColor = appearance.getColorStateList(attr);break;case com.android.internal.R.styleable.TextAppearance_textColorHint:textColorHint = appearance.getColorStateList(attr);break;case com.android.internal.R.styleable.TextAppearance_textColorLink:textColorLink = appearance.getColorStateList(attr);break;case com.android.internal.R.styleable.TextAppearance_textSize:textSize = appearance.getDimensionPixelSize(attr, textSize);break;case com.android.internal.R.styleable.TextAppearance_typeface:typefaceIndex = appearance.getInt(attr, -1);break;case com.android.internal.R.styleable.TextAppearance_fontFamily:if (!context.isRestricted() && context.canLoadUnsafeResources()) {try {fontTypeface = appearance.getFont(attr);} catch (UnsupportedOperationException| Resources.NotFoundException e) {// Expected if it is not a font resource.}}if (fontTypeface == null) {fontFamily = appearance.getString(attr);}break;case com.android.internal.R.styleable.TextAppearance_textStyle:styleIndex = appearance.getInt(attr, -1);break;case com.android.internal.R.styleable.TextAppearance_textAllCaps:allCaps = appearance.getBoolean(attr, false);break;case com.android.internal.R.styleable.TextAppearance_shadowColor:shadowcolor = appearance.getInt(attr, 0);break;case com.android.internal.R.styleable.TextAppearance_shadowDx:dx = appearance.getFloat(attr, 0);break;case com.android.internal.R.styleable.TextAppearance_shadowDy:dy = appearance.getFloat(attr, 0);break;case com.android.internal.R.styleable.TextAppearance_shadowRadius:r = appearance.getFloat(attr, 0);break;case com.android.internal.R.styleable.TextAppearance_elegantTextHeight:elegant = appearance.getBoolean(attr, false);break;case com.android.internal.R.styleable.TextAppearance_letterSpacing:letterSpacing = appearance.getFloat(attr, 0);break;case com.android.internal.R.styleable.TextAppearance_fontFeatureSettings:fontFeatureSettings = appearance.getString(attr);break;}}appearance.recycle();}boolean editable = getDefaultEditable();CharSequence inputMethod = null;int numeric = 0;CharSequence digits = null;boolean phone = false;boolean autotext = false;int autocap = -1;int buffertype = 0;boolean selectallonfocus = false;Drawable drawableLeft = null, drawableTop = null, drawableRight = null,drawableBottom = null, drawableStart = null, drawableEnd = null;ColorStateList drawableTint = null;PorterDuff.Mode drawableTintMode = null;int drawablePadding = 0;int ellipsize = -1;boolean singleLine = false;int maxlength = -1;CharSequence text = "";CharSequence hint = null;boolean password = false;float autoSizeMinTextSizeInPx = UNSET_AUTO_SIZE_UNIFORM_CONFIGURATION_VALUE;float autoSizeMaxTextSizeInPx = UNSET_AUTO_SIZE_UNIFORM_CONFIGURATION_VALUE;float autoSizeStepGranularityInPx = UNSET_AUTO_SIZE_UNIFORM_CONFIGURATION_VALUE;int inputType = EditorInfo.TYPE_NULL;
//从attrs中取出在R.styleable.TextView中声明过的属性。a = theme.obtainStyledAttributes(attrs, com.android.internal.R.styleable.TextView, defStyleAttr, defStyleRes);int n = a.getIndexCount();boolean fromResourceId = false;for (int i = 0; i < n; i++) {int attr = a.getIndex(i);switch (attr) {case com.android.internal.R.styleable.TextView_editable:editable = a.getBoolean(attr, editable);break;case com.android.internal.R.styleable.TextView_inputMethod:inputMethod = a.getText(attr);break;case com.android.internal.R.styleable.TextView_numeric:numeric = a.getInt(attr, numeric);break;case com.android.internal.R.styleable.TextView_digits:digits = a.getText(attr);break;case com.android.internal.R.styleable.TextView_phoneNumber:phone = a.getBoolean(attr, phone);break;case com.android.internal.R.styleable.TextView_autoText:autotext = a.getBoolean(attr, autotext);break;case com.android.internal.R.styleable.TextView_capitalize:autocap = a.getInt(attr, autocap);break;case com.android.internal.R.styleable.TextView_bufferType:buffertype = a.getInt(attr, buffertype);break;case com.android.internal.R.styleable.TextView_selectAllOnFocus:selectallonfocus = a.getBoolean(attr, selectallonfocus);break;case com.android.internal.R.styleable.TextView_autoLink:mAutoLinkMask = a.getInt(attr, 0);break;case com.android.internal.R.styleable.TextView_linksClickable:mLinksClickable = a.getBoolean(attr, true);break;case com.android.internal.R.styleable.TextView_drawableLeft:drawableLeft = a.getDrawable(attr);break;case com.android.internal.R.styleable.TextView_drawableTop:drawableTop = a.getDrawable(attr);break;case com.android.internal.R.styleable.TextView_drawableRight:drawableRight = a.getDrawable(attr);break;case com.android.internal.R.styleable.TextView_drawableBottom:drawableBottom = a.getDrawable(attr);break;case com.android.internal.R.styleable.TextView_drawableStart:drawableStart = a.getDrawable(attr);break;case com.android.internal.R.styleable.TextView_drawableEnd:drawableEnd = a.getDrawable(attr);break;case com.android.internal.R.styleable.TextView_drawableTint:drawableTint = a.getColorStateList(attr);break;case com.android.internal.R.styleable.TextView_drawableTintMode:drawableTintMode = Drawable.parseTintMode(a.getInt(attr, -1), drawableTintMode);break;case com.android.internal.R.styleable.TextView_drawablePadding:drawablePadding = a.getDimensionPixelSize(attr, drawablePadding);break;case com.android.internal.R.styleable.TextView_maxLines:setMaxLines(a.getInt(attr, -1));break;case com.android.internal.R.styleable.TextView_maxHeight:setMaxHeight(a.getDimensionPixelSize(attr, -1));break;case com.android.internal.R.styleable.TextView_lines:setLines(a.getInt(attr, -1));break;case com.android.internal.R.styleable.TextView_height:setHeight(a.getDimensionPixelSize(attr, -1));break;case com.android.internal.R.styleable.TextView_minLines:setMinLines(a.getInt(attr, -1));break;case com.android.internal.R.styleable.TextView_minHeight:setMinHeight(a.getDimensionPixelSize(attr, -1));break;case com.android.internal.R.styleable.TextView_maxEms:setMaxEms(a.getInt(attr, -1));break;case com.android.internal.R.styleable.TextView_maxWidth:setMaxWidth(a.getDimensionPixelSize(attr, -1));break;case com.android.internal.R.styleable.TextView_ems:setEms(a.getInt(attr, -1));break;case com.android.internal.R.styleable.TextView_width:setWidth(a.getDimensionPixelSize(attr, -1));break;case com.android.internal.R.styleable.TextView_minEms:setMinEms(a.getInt(attr, -1));break;case com.android.internal.R.styleable.TextView_minWidth:setMinWidth(a.getDimensionPixelSize(attr, -1));break;case com.android.internal.R.styleable.TextView_gravity:setGravity(a.getInt(attr, -1));break;case com.android.internal.R.styleable.TextView_hint:hint = a.getText(attr);break;case com.android.internal.R.styleable.TextView_text:fromResourceId = true;text = a.getText(attr);break;case com.android.internal.R.styleable.TextView_scrollHorizontally:if (a.getBoolean(attr, false)) {setHorizontallyScrolling(true);}break;case com.android.internal.R.styleable.TextView_singleLine:singleLine = a.getBoolean(attr, singleLine);break;case com.android.internal.R.styleable.TextView_ellipsize:ellipsize = a.getInt(attr, ellipsize);break;case com.android.internal.R.styleable.TextView_marqueeRepeatLimit:setMarqueeRepeatLimit(a.getInt(attr, mMarqueeRepeatLimit));break;case com.android.internal.R.styleable.TextView_includeFontPadding:if (!a.getBoolean(attr, true)) {setIncludeFontPadding(false);}break;case com.android.internal.R.styleable.TextView_cursorVisible:if (!a.getBoolean(attr, true)) {setCursorVisible(false);}break;case com.android.internal.R.styleable.TextView_maxLength:maxlength = a.getInt(attr, -1);break;case com.android.internal.R.styleable.TextView_textScaleX:setTextScaleX(a.getFloat(attr, 1.0f));break;case com.android.internal.R.styleable.TextView_freezesText:mFreezesText = a.getBoolean(attr, false);break;case com.android.internal.R.styleable.TextView_shadowColor:shadowcolor = a.getInt(attr, 0);break;case com.android.internal.R.styleable.TextView_shadowDx:dx = a.getFloat(attr, 0);break;case com.android.internal.R.styleable.TextView_shadowDy:dy = a.getFloat(attr, 0);break;case com.android.internal.R.styleable.TextView_shadowRadius:r = a.getFloat(attr, 0);break;case com.android.internal.R.styleable.TextView_enabled:setEnabled(a.getBoolean(attr, isEnabled()));break;case com.android.internal.R.styleable.TextView_textColorHighlight:textColorHighlight = a.getColor(attr, textColorHighlight);break;case com.android.internal.R.styleable.TextView_textColor:textColor = a.getColorStateList(attr);break;case com.android.internal.R.styleable.TextView_textColorHint:textColorHint = a.getColorStateList(attr);break;case com.android.internal.R.styleable.TextView_textColorLink:textColorLink = a.getColorStateList(attr);break;case com.android.internal.R.styleable.TextView_textSize:textSize = a.getDimensionPixelSize(attr, textSize);break;case com.android.internal.R.styleable.TextView_typeface:typefaceIndex = a.getInt(attr, typefaceIndex);break;case com.android.internal.R.styleable.TextView_textStyle:styleIndex = a.getInt(attr, styleIndex);break;case com.android.internal.R.styleable.TextView_fontFamily:if (!context.isRestricted() && context.canLoadUnsafeResources()) {try {fontTypeface = a.getFont(attr);} catch (UnsupportedOperationException | Resources.NotFoundException e) {// Expected if it is not a resource reference or if it is a reference to// another resource type.}}if (fontTypeface == null) {fontFamily = a.getString(attr);}fontFamilyExplicit = true;break;case com.android.internal.R.styleable.TextView_password:password = a.getBoolean(attr, password);break;case com.android.internal.R.styleable.TextView_lineSpacingExtra:mSpacingAdd = a.getDimensionPixelSize(attr, (int) mSpacingAdd);break;case com.android.internal.R.styleable.TextView_lineSpacingMultiplier:mSpacingMult = a.getFloat(attr, mSpacingMult);break;case com.android.internal.R.styleable.TextView_inputType:inputType = a.getInt(attr, EditorInfo.TYPE_NULL);break;case com.android.internal.R.styleable.TextView_allowUndo:createEditorIfNeeded();mEditor.mAllowUndo = a.getBoolean(attr, true);break;case com.android.internal.R.styleable.TextView_imeOptions:createEditorIfNeeded();mEditor.createInputContentTypeIfNeeded();mEditor.mInputContentType.imeOptions = a.getInt(attr,mEditor.mInputContentType.imeOptions);break;case com.android.internal.R.styleable.TextView_imeActionLabel:createEditorIfNeeded();mEditor.createInputContentTypeIfNeeded();mEditor.mInputContentType.imeActionLabel = a.getText(attr);break;case com.android.internal.R.styleable.TextView_imeActionId:createEditorIfNeeded();mEditor.createInputContentTypeIfNeeded();mEditor.mInputContentType.imeActionId = a.getInt(attr,mEditor.mInputContentType.imeActionId);break;case com.android.internal.R.styleable.TextView_privateImeOptions:setPrivateImeOptions(a.getString(attr));break;case com.android.internal.R.styleable.TextView_editorExtras:try {setInputExtras(a.getResourceId(attr, 0));} catch (XmlPullParserException e) {Log.w(LOG_TAG, "Failure reading input extras", e);} catch (IOException e) {Log.w(LOG_TAG, "Failure reading input extras", e);}break;case com.android.internal.R.styleable.TextView_textCursorDrawable:mCursorDrawableRes = a.getResourceId(attr, 0);break;case com.android.internal.R.styleable.TextView_textSelectHandleLeft:mTextSelectHandleLeftRes = a.getResourceId(attr, 0);break;case com.android.internal.R.styleable.TextView_textSelectHandleRight:mTextSelectHandleRightRes = a.getResourceId(attr, 0);break;case com.android.internal.R.styleable.TextView_textSelectHandle:mTextSelectHandleRes = a.getResourceId(attr, 0);break;case com.android.internal.R.styleable.TextView_textEditSuggestionItemLayout:mTextEditSuggestionItemLayout = a.getResourceId(attr, 0);break;case com.android.internal.R.styleable.TextView_textEditSuggestionContainerLayout:mTextEditSuggestionContainerLayout = a.getResourceId(attr, 0);break;case com.android.internal.R.styleable.TextView_textEditSuggestionHighlightStyle:mTextEditSuggestionHighlightStyle = a.getResourceId(attr, 0);break;case com.android.internal.R.styleable.TextView_textIsSelectable:setTextIsSelectable(a.getBoolean(attr, false));break;case com.android.internal.R.styleable.TextView_textAllCaps:allCaps = a.getBoolean(attr, false);break;case com.android.internal.R.styleable.TextView_elegantTextHeight:elegant = a.getBoolean(attr, false);break;case com.android.internal.R.styleable.TextView_letterSpacing:letterSpacing = a.getFloat(attr, 0);break;case com.android.internal.R.styleable.TextView_fontFeatureSettings:fontFeatureSettings = a.getString(attr);break;case com.android.internal.R.styleable.TextView_breakStrategy:mBreakStrategy = a.getInt(attr, Layout.BREAK_STRATEGY_SIMPLE);break;case com.android.internal.R.styleable.TextView_hyphenationFrequency:mHyphenationFrequency = a.getInt(attr, Layout.HYPHENATION_FREQUENCY_NONE);break;case com.android.internal.R.styleable.TextView_autoSizeTextType:mAutoSizeTextType = a.getInt(attr, AUTO_SIZE_TEXT_TYPE_NONE);break;case com.android.internal.R.styleable.TextView_autoSizeStepGranularity:autoSizeStepGranularityInPx = a.getDimension(attr,UNSET_AUTO_SIZE_UNIFORM_CONFIGURATION_VALUE);break;case com.android.internal.R.styleable.TextView_autoSizeMinTextSize:autoSizeMinTextSizeInPx = a.getDimension(attr,UNSET_AUTO_SIZE_UNIFORM_CONFIGURATION_VALUE);break;case com.android.internal.R.styleable.TextView_autoSizeMaxTextSize:autoSizeMaxTextSizeInPx = a.getDimension(attr,UNSET_AUTO_SIZE_UNIFORM_CONFIGURATION_VALUE);break;case com.android.internal.R.styleable.TextView_autoSizePresetSizes:final int autoSizeStepSizeArrayResId = a.getResourceId(attr, 0);if (autoSizeStepSizeArrayResId > 0) {final TypedArray autoSizePresetTextSizes = a.getResources().obtainTypedArray(autoSizeStepSizeArrayResId);setupAutoSizeUniformPresetSizes(autoSizePresetTextSizes);autoSizePresetTextSizes.recycle();}break;case com.android.internal.R.styleable.TextView_justificationMode:mJustificationMode = a.getInt(attr, Layout.JUSTIFICATION_MODE_NONE);break;}}a.recycle();
R.styleable.TextView的定义如下:
R.styleable.TextAppearance
一般Theme对textAppearance的使用:
themes.xml
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
