- 浏览: 1044435 次
- 性别:
- 来自: US
文章分类
最新评论
-
ever丶唯爱:
有activiti的视频吗?
Activiti介绍及视频教程 -
A_T_Being:
好东西,在百度盘上面,可以下载来看。
Redis介绍及视频教程 -
zhuchao_ko:
这个世界上只有两种语言 一种没人用的 一种被骂 的 我一直相信 ...
程序员将面临再次洗牌,你作何选择? -
ljmomo:
微软 手机 现在 已经不挂 诺基亚logo 。还有就是 微软 ...
程序员将面临再次洗牌,你作何选择? -
benwg:
楼主,MacOS是基于BSD系统的,真怀疑你是否从事多年的软件 ...
程序员将面临再次洗牌,你作何选择?
Android菜鸟的成长笔记(6)——剖析源码学自定义主题Theme
还记得在Android菜鸟的成长笔记(3)中我们曾经遇到了一个问题吗?"这个界面和真真的QQ界面还有点不同的就是上面的标题myFirstApp,怎么去掉这个标题呢?",当时我直接在AndroidMainfest.xml中添加了一个属性:
android:theme="@android:style/Theme.NoTitleBar"
可能有的朋友就会迷惑了,为什么添加了这个属性就可以了。这一篇文章将让我们一起翻开Android系统源代码来揭开困扰大家的关于主题使用以及自定义的谜团。
一、样式(Style)与主题(Theme)
在Android的应用的资源文件中有一个style.xml文件,这个文件是干什么用的呢?我们有时候经常需要对某个类型的组件指定大致相似的格式,比如字体、颜色、背景色等,如果我们每次都为某个View组件去重复指定这些属性,这无疑会产生大量的工作,而且还不利于后期的代码修改和维护。而Style就是一个样式的格式,这个格式可以被多个View组件所使用,也可以说是一个样式的集合类,被需要这一类样式集合的View组件所使用。例如我们前面写的QQ登录界面中的登录按钮,我们可以给定义一个样式
<style name="buttonStyle"> <item name="android:background">@drawable/login_button_nor</item> <item name="android:textColor">@color/buttonTextColor</item> </style>
在布局文件中引入样式
<Button android:layout_width="270dip" android:layout_height="40dip" android:text="@string/login_button" style="@style/buttonStyle" />与样式非常相似,主题资源的xml文件通常也放在/res/values目录下,主题相当于整个应用或者某个Activity的样式,换句话说主题是针对窗体级别或整个应用程序的样式。与样式比较,样式是针对窗体内元素的样式。主题的设置有两种方式
(1)在AndroidMainfest.xml中为Activity或者application指定主题
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" > <activity android:name="com.example.myfirstapp.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
上面AndroidMainfest.xml代码中给整个应用指定了一个主题,这个主题是没有标题栏的系统主题。
(2)在Activity创建时调用 setTheme方法(必须在setContentView前面调用)来给某个Activity添加主题。
二、剖析主题(Theme)资源
我们先来创建一个工程名字为helloworld,然后打开它的AndroiodMainfest.xml文件
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.helloworld.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
可以看到我们在创建工程时,已经默认给我们的整个应用添加了一个主题
android:theme="@style/AppTheme"打开我们资源文件res/values/下面的styles.xml文件,可以看到在样式文件中有一个名字为AppTheme的样式,如下:
<resources> <!-- Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices. --> <style name="AppBaseTheme" parent="android:Theme.Light"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. --> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- All customizations that are NOT specific to a particular API-level can go here. --> </style> </resources>我们可以看到,这个AppTheme的样式继承自上面的AppBaseTheme。而AppBaseTheme又继承自系统的一个样式Theme.Light,打开Android系统源代码找到Theme.xml文件中的Theme.Light如下:
<!-- Theme for a light background with dark text on top. Set your activity to this theme if you would like such an appearance. As with the default theme, you should try to assume little more than that the background will be a light color. --> <style name="Theme.Light"> <item name="windowBackground">@drawable/screen_background_light</item> <item name="colorBackground">@android:color/background_light</item> <item name="colorForeground">@color/bright_foreground_light</item> <item name="colorForegroundInverse">@android:color/bright_foreground_light_inverse</item> <item name="textColorPrimary">@android:color/primary_text_light</item> <item name="textColorSecondary">@android:color/secondary_text_light</item> <item name="textColorTertiary">@android:color/tertiary_text_light</item> <item name="textColorPrimaryInverse">@android:color/primary_text_dark</item> <item name="textColorSecondaryInverse">@android:color/secondary_text_dark</item> <item name="textColorTertiaryInverse">@android:color/tertiary_text_dark</item> <item name="textColorPrimaryDisableOnly">@android:color/primary_text_light_disable_only</item> <item name="textColorPrimaryInverseDisableOnly">@android:color/primary_text_dark_disable_only</item> <item name="textColorPrimaryNoDisable">@android:color/primary_text_light_nodisable</item> <item name="textColorSecondaryNoDisable">@android:color/secondary_text_light_nodisable</item> <item name="textColorPrimaryInverseNoDisable">@android:color/primary_text_dark_nodisable</item> <item name="textColorSecondaryInverseNoDisable">@android:color/secondary_text_dark_nodisable</item> <item name="textColorHint">@android:color/hint_foreground_light</item> <item name="textColorHintInverse">@android:color/hint_foreground_dark</item> <item name="popupWindowStyle">@android:style/Widget.PopupWindow</item> <item name="textCheckMark">@android:drawable/indicator_check_mark_light</item> <item name="textCheckMarkInverse">@android:drawable/indicator_check_mark_dark</item> <item name="gestureOverlayViewStyle">@android:style/Widget.GestureOverlayView.White</item> <item name="expandableListViewStyle">@android:style/Widget.ExpandableListView.White</item> <item name="listViewStyle">@android:style/Widget.ListView.White</item> <item name="listDivider">@drawable/divider_horizontal_bright</item> <item name="listSeparatorTextViewStyle">@android:style/Widget.TextView.ListSeparator.White</item> <item name="progressBarStyle">@android:style/Widget.ProgressBar.Inverse</item> <item name="progressBarStyleSmall">@android:style/Widget.ProgressBar.Small.Inverse</item> <item name="progressBarStyleLarge">@android:style/Widget.ProgressBar.Large.Inverse</item> <item name="progressBarStyleInverse">@android:style/Widget.ProgressBar</item> <item name="progressBarStyleSmallInverse">@android:style/Widget.ProgressBar.Small</item> <item name="progressBarStyleLargeInverse">@android:style/Widget.ProgressBar.Large</item> </style>样式的继承有两种方式,一种是上面看到的parent="",还有一种就是用”."的方式,上面的Theme.Light继承自Theme。这两种继承有什么区别呢?一个相当于咱们类之间的继承extend,另一个相当于内部类,也可以使用外部类的属性和方法。我们再来看看Theme.Light的父类Theme的样式定义。
<style name="Theme"> <item name="colorForeground">@android:color/bright_foreground_dark</item> <item name="colorForegroundInverse">@android:color/bright_foreground_dark_inverse</item> <item name="colorBackground">@android:color/background_dark</item> <item name="colorBackgroundCacheHint">?android:attr/colorBackground</item> <item name="disabledAlpha">0.5</item> <item name="backgroundDimAmount">0.6</item> <!-- Text styles --> <item name="textAppearance">@android:style/TextAppearance</item> <item name="textAppearanceInverse">@android:style/TextAppearance.Inverse</item> <item name="textColorPrimary">@android:color/primary_text_dark</item> <item name="textColorSecondary">@android:color/secondary_text_dark</item> <item name="textColorTertiary">@android:color/tertiary_text_dark</item> <item name="textColorPrimaryInverse">@android:color/primary_text_light</item> <item name="textColorSecondaryInverse">@android:color/secondary_text_light</item> <item name="textColorTertiaryInverse">@android:color/tertiary_text_light</item> <item name="textColorPrimaryDisableOnly">@android:color/primary_text_dark_disable_only</item> <item name="textColorPrimaryInverseDisableOnly">@android:color/primary_text_light_disable_only</item> <item name="textColorPrimaryNoDisable">@android:color/primary_text_dark_nodisable</item> <item name="textColorSecondaryNoDisable">@android:color/secondary_text_dark_nodisable</item> <item name="textColorPrimaryInverseNoDisable">@android:color/primary_text_light_nodisable</item> <item name="textColorSecondaryInverseNoDisable">@android:color/secondary_text_light_nodisable</item> <item name="textColorHint">@android:color/hint_foreground_dark</item> <item name="textColorHintInverse">@android:color/hint_foreground_light</item> <item name="textColorSearchUrl">@android:color/search_url_text</item> <item name="textAppearanceLarge">@android:style/TextAppearance.Large</item> <item name="textAppearanceMedium">@android:style/TextAppearance.Medium</item> <item name="textAppearanceSmall">@android:style/TextAppearance.Small</item> <item name="textAppearanceLargeInverse">@android:style/TextAppearance.Large.Inverse</item> <item name="textAppearanceMediumInverse">@android:style/TextAppearance.Medium.Inverse</item> <item name="textAppearanceSmallInverse">@android:style/TextAppearance.Small.Inverse</item> <item name="textAppearanceSearchResultTitle">@android:style/TextAppearance.SearchResult.Title</item> <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.SearchResult.Subtitle</item> <item name="textAppearanceButton">@android:style/TextAppearance.Widget.Button</item> <item name="candidatesTextStyleSpans">@android:string/candidates_style</item> <item name="textCheckMark">@android:drawable/indicator_check_mark_dark</item> <item name="textCheckMarkInverse">@android:drawable/indicator_check_mark_light</item> <!-- Button styles --> <item name="buttonStyle">@android:style/Widget.Button</item> <item name="buttonStyleSmall">@android:style/Widget.Button.Small</item> <item name="buttonStyleInset">@android:style/Widget.Button.Inset</item> <item name="buttonStyleToggle">@android:style/Widget.Button.Toggle</item> <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> <!-- @hide --> <item name="searchResultListItemHeight">58dip</item> <item name="listDivider">@drawable/divider_horizontal_dark</item> <item name="listSeparatorTextViewStyle">@android:style/Widget.TextView.ListSeparator</item> <item name="listChoiceIndicatorSingle">@android:drawable/btn_radio</item> <item name="listChoiceIndicatorMultiple">@android:drawable/btn_check</item> <item name="expandableListPreferredItemPaddingLeft">40dip</item> <item name="expandableListPreferredChildPaddingLeft"> ?android:attr/expandableListPreferredItemPaddingLeft</item> <item name="expandableListPreferredItemIndicatorLeft">3dip</item> <item name="expandableListPreferredItemIndicatorRight">33dip</item> <item name="expandableListPreferredChildIndicatorLeft"> ?android:attr/expandableListPreferredItemIndicatorLeft</item> <item name="expandableListPreferredChildIndicatorRight"> ?android:attr/expandableListPreferredItemIndicatorRight</item> <!-- Gallery attributes --> <item name="galleryItemBackground">@android:drawable/gallery_item_background</item> <!-- Window attributes --> <item name="windowBackground">@android:drawable/screen_background_dark</item> <item name="windowFrame">@null</item> <item name="windowNoTitle">false</item> <item name="windowFullscreen">false</item> <item name="windowIsFloating">false</item> <item name="windowContentOverlay">@android:drawable/title_bar_shadow</item> <item name="windowShowWallpaper">false</item> <item name="windowTitleStyle">@android:style/WindowTitle</item> <item name="windowTitleSize">25dip</item> <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground</item> <item name="android:windowAnimationStyle">@android:style/Animation.Activity</item> <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item> <!-- Dialog attributes --> <item name="alertDialogStyle">@android:style/AlertDialog</item> <!-- Panel attributes --> <item name="panelBackground">@android:drawable/menu_background</item> <item name="panelFullBackground">@android:drawable/menu_background_fill_parent_width</item> <!-- These three attributes do not seems to be used by the framework. Declared public though --> <item name="panelColorBackground">#000</item> <item name="panelColorForeground">?android:attr/textColorPrimary</item> <item name="panelTextAppearance">?android:attr/textAppearance</item> <!-- Scrollbar attributes --> <item name="scrollbarFadeDuration">250</item> <item name="scrollbarDefaultDelayBeforeFade">300</item> <item name="scrollbarSize">10dip</item> <item name="scrollbarThumbHorizontal">@android:drawable/scrollbar_handle_horizontal</item> <item name="scrollbarThumbVertical">@android:drawable/scrollbar_handle_vertical</item> <item name="scrollbarTrackHorizontal">@null</item> <item name="scrollbarTrackVertical">@null</item> <!-- Text selection handle attributes --> <item name="textSelectHandleLeft">@android:drawable/text_select_handle_left</item> <item name="textSelectHandleRight">@android:drawable/text_select_handle_right</item> <item name="textSelectHandle">@android:drawable/text_select_handle_middle</item> <item name="textSelectHandleWindowStyle">@android:style/Widget.TextSelectHandle</item> <!-- Widget styles --> <item name="absListViewStyle">@android:style/Widget.AbsListView</item> <item name="autoCompleteTextViewStyle">@android:style/Widget.AutoCompleteTextView</item> <item name="checkboxStyle">@android:style/Widget.CompoundButton.CheckBox</item> <item name="dropDownListViewStyle">@android:style/Widget.ListView.DropDown</item> <item name="editTextStyle">@android:style/Widget.EditText</item> <item name="expandableListViewStyle">@android:style/Widget.ExpandableListView</item> <item name="expandableListViewWhiteStyle">@android:style/Widget.ExpandableListView.White</item> <item name="galleryStyle">@android:style/Widget.Gallery</item> <item name="gestureOverlayViewStyle">@android:style/Widget.GestureOverlayView</item> <item name="gridViewStyle">@android:style/Widget.GridView</item> <item name="imageButtonStyle">@android:style/Widget.ImageButton</item> <item name="imageWellStyle">@android:style/Widget.ImageWell</item> <item name="listViewStyle">@android:style/Widget.ListView</item> <item name="listViewWhiteStyle">@android:style/Widget.ListView.White</item> <item name="popupWindowStyle">@android:style/Widget.PopupWindow</item> <item name="progressBarStyle">@android:style/Widget.ProgressBar</item> <item name="progressBarStyleHorizontal">@android:style/Widget.ProgressBar.Horizontal</item> <item name="progressBarStyleSmall">@android:style/Widget.ProgressBar.Small</item> <item name="progressBarStyleSmallTitle">@android:style/Widget.ProgressBar.Small.Title</item> <item name="progressBarStyleLarge">@android:style/Widget.ProgressBar.Large</item> <item name="progressBarStyleInverse">@android:style/Widget.ProgressBar.Inverse</item> <item name="progressBarStyleSmallInverse">@android:style/Widget.ProgressBar.Small.Inverse</item> <item name="progressBarStyleLargeInverse">@android:style/Widget.ProgressBar.Large.Inverse</item> <item name="seekBarStyle">@android:style/Widget.SeekBar</item> <item name="ratingBarStyle">@android:style/Widget.RatingBar</item> <item name="ratingBarStyleIndicator">@android:style/Widget.RatingBar.Indicator</item> <item name="ratingBarStyleSmall">@android:style/Widget.RatingBar.Small</item> <item name="radioButtonStyle">@android:style/Widget.CompoundButton.RadioButton</item> <item name="scrollViewStyle">@android:style/Widget.ScrollView</item> <item name="horizontalScrollViewStyle">@android:style/Widget.HorizontalScrollView</item> <item name="spinnerStyle">@android:style/Widget.Spinner</item> <item name="starStyle">@android:style/Widget.CompoundButton.Star</item> <item name="tabWidgetStyle">@android:style/Widget.TabWidget</item> <item name="textViewStyle">@android:style/Widget.TextView</item> <item name="webTextViewStyle">@android:style/Widget.WebTextView</item> <item name="webViewStyle">@android:style/Widget.WebView</item> <item name="dropDownItemStyle">@android:style/Widget.DropDownItem</item> <item name="spinnerDropDownItemStyle">@android:style/Widget.DropDownItem.Spinner</item> <item name="spinnerItemStyle">@android:style/Widget.TextView.SpinnerItem</item> <item name="dropDownHintAppearance">@android:style/TextAppearance.Widget.DropDownHint</item> <item name="keyboardViewStyle">@android:style/Widget.KeyboardView</item> <item name="quickContactBadgeStyleWindowSmall">@android:style/Widget.QuickContactBadge.WindowSmall</item> <item name="quickContactBadgeStyleWindowMedium">@android:style/Widget.QuickContactBadge.WindowMedium</item> <item name="quickContactBadgeStyleWindowLarge">@android:style/Widget.QuickContactBadge.WindowLarge</item> <item name="quickContactBadgeStyleSmallWindowSmall">@android:style/Widget.QuickContactBadgeSmall.WindowSmall</item> <item name="quickContactBadgeStyleSmallWindowMedium">@android:style/Widget.QuickContactBadgeSmall.WindowMedium</item> <item name="quickContactBadgeStyleSmallWindowLarge">@android:style/Widget.QuickContactBadgeSmall.WindowLarge</item> <!-- Preference styles --> <item name="preferenceScreenStyle">@android:style/Preference.PreferenceScreen</item> <item name="preferenceCategoryStyle">@android:style/Preference.Category</item> <item name="preferenceStyle">@android:style/Preference</item> <item name="preferenceInformationStyle">@android:style/Preference.Information</item> <item name="checkBoxPreferenceStyle">@android:style/Preference.CheckBoxPreference</item> <item name="yesNoPreferenceStyle">@android:style/Preference.DialogPreference.YesNoPreference</item> <item name="dialogPreferenceStyle">@android:style/Preference.DialogPreference</item> <item name="editTextPreferenceStyle">@android:style/Preference.DialogPreference.EditTextPreference</item> <item name="ringtonePreferenceStyle">@android:style/Preference.RingtonePreference</item> <item name="preferenceLayoutChild">@android:layout/preference_child</item> <!-- Search widget styles --> <item name="searchWidgetCorpusItemBackground">@android:color/search_widget_corpus_item_background</item> </style>
我们可以看到里面定义了关于我们整个应用中文字的样式,按钮的样式,列表的样式,画廊的样式,窗体的样式,对话框的样式等。这个样式是系统的默认样式,也是最符合HOLO的样式。Theme中定义的是最基本的主题样式,Theme的样式扩展样式有我们上面的Theme.Light还有Theme.NoTitleBar、Theme.NoTitleBar.Fullscreen、Theme.Light.NoTitleBar、Theme.Light.NoTitleBar.Fullscreen、Theme.Black、......
三、自定义主题
有了上面对Theme的了解之后,下面我们通过改变标题栏来自定义主题样式,首先继承Theme,标题栏是与窗体样式(Window attributes)相关的样式,我们在Theme.xml中找到这几句代码.
<!-- Window attributes --> <item name="windowBackground">@android:drawable/screen_background_dark</item> <item name="windowFrame">@null</item> <item name="windowNoTitle">false</item> <item name="windowFullscreen">false</item> <item name="windowIsFloating">false</item> <item name="windowContentOverlay">@android:drawable/title_bar_shadow</item> <item name="windowShowWallpaper">false</item> <item name="windowTitleStyle">@android:style/WindowTitle</item> <item name="windowTitleSize">25dip</item> <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground</item> <item name="android:windowAnimationStyle">@android:style/Animation.Activity</item> <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
将上面主题中Title的大小和背景覆盖
<!-- 自定义的主题样式 --> <style name="myTheme" parent="android:Theme"> <item name="android:windowTitleBackgroundStyle">@style/myThemeStyle</item> <item name="android:windowTitleSize">50dip</item> </style> <!-- 主题中Title的背景样式 --> <style name="myThemeStyle"> <item name="android:background">#FF0000</item> </style>
默认主题样式
自定义主题样式
如果有的朋友还想改变整个应用的字体、或者风格都可以通过继承Theme覆盖原有的样式来达到自定义的效果。
Java学习交流群142979499 | |
Android学习交流群311273384 |
相关推荐
菜鸟成长手册2009——CPU-内存-硬盘篇 - 硬件知识精华菜鸟成长手册2009——CPU-内存-硬盘篇 - 硬件知识精华菜鸟成长手册2009——CPU-内存-硬盘篇 - 硬件知识精华菜鸟成长手册2009——CPU-内存-硬盘篇 - 硬件知识精华...
Android菜鸟成长笔记(十三)——碎片(一)一篇完整源码 地址:http://blog.csdn.net/zenail501129/article/details/25473829 保证代码正确。
Android菜鸟的成长笔记——Spinner 省市县三级地址选择-附件资源
php程序员菜鸟成长手记——php入门教程
android商城源码,功能齐全,注释明确,是学习,二次开发的最佳选择,带数据
菜鸟先飞笔记——金融生学神经网络keras一、下载Anaconda二、安装三 、准备工作四、安装keras五、试运行 一、下载Anaconda 下载链接:清华镜像。按照自己系统选择最新版的anaconda3。 二、安装 默认安装,可以自己...
菜鸟也玩LINUX——brk()漏洞重提.pdf
IOS 菜鸟笔记 之 项目 三 源码 blog地址:http://blog.csdn.net/tim_shadow/article/details/45717561
android菜鸟练手小项目之自定义日历,涵盖LitePal数据库,极光推送,图灵机器人聊天,可作为新手的练手小项目。
菜鸟构建个人网站——“纯真年代”建站全过程(五).pdf
本javascript菜鸟堂上笔记探索部分仅供个人使用,切勿用于商业用途,由ekom.cn提供,谢谢!
菜鸟学习ARM——安装交叉编译链记录,及编译jpeg
IOS 菜鸟笔记 之 项目 一 ( 源码 ) 博客地址: http://blog.csdn.net/tim_shadow/article/details/45311447
菜鸟窝企业项目课程《菜鸟商城》的源码
34--[菜鸟闯关].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码34--[菜鸟闯关].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码34--[菜鸟闯关].zip源码scratch2.0 3.0编程项目源文件源码案例素材源...
嵌入式系统开发之道菜鸟成长日志与项目经理的私房菜pdf文件,非扫描版哦, 对开发者还是有些帮助的。
为参加计算机二级VFP编写的一个实用教程,语言通俗易懂
菜鸟成长必学电脑硬件基础教材手册,很实用的电脑基础教材.
ASP.NET源码——[电子商务]菜鸟商城系统.zip