1.主题theme
theme是应用的主题,或者说风格。通过设置主题可以改变应用的相关皮肤。
一般主题作用于整个应用,即对应的是application,但有时候部分界面需要特殊的处理,比如为一个特定的activity设置一个单独的皮肤。
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
……
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:theme="@style/AppTheme.theme1">
……
</activity>
</application>
上面在配置文件中分别从两个地方设置了主题:
①在application中设置,这个就是全局的,如果不再单独为某个activity设置主题,那么activity的主题就是“@style/AppTheme”。
②在activity中设置,比如为MainActivity单独设置一个主题为:@style/AppTheme.theme1。
所以主题的作用域就是application和activity,不涉及到内部的View。
当然,除了在xml中设置,也可以用代码动态设置:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(android.R.style.mytheme);
setContentView(R.layout.activity_main);
}
注意:设置主题要在setContentView()之前。
2.常见的系统主题
android:theme="@android:style/Theme.Dialog" 将一个Activity显示为对话框模式
android:theme="@android:style/Theme.NoTitleBar" 不显示应用程序标题栏
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" 不显示应用程序标题栏,并全屏
android:theme="Theme.Light" 背景为白色
android:theme="Theme.Light.NoTitleBar" 白色背景并无标题栏
android:theme="Theme.Light.NoTitleBar.Fullscreen" 白色背景,无标题栏,全屏
android:theme="Theme.Black" 背景黑色
android:theme="Theme.Black.NoTitleBar" 黑色背景并无标题栏
android:theme="Theme.Black.NoTitleBar.Fullscreen" 黑色背景,无标题栏,全屏
android:theme="Theme.Wallpaper" 用系统桌面为应用程序背景
android:theme="Theme.Wallpaper.NoTitleBar" 用系统桌面为应用程序背景,且无标题栏
android:theme="Theme.Wallpaper.NoTitleBar.Fullscreen" 用系统桌面为应用程序背景,无标题栏,全屏
android:theme="Translucent" 半透明
android:theme="Theme.Translucent.NoTitleBar" 半透明、无标题栏
android:theme="Theme.Translucent.NoTitleBar.Fullscreen" 半透明、无标题栏、全屏
android:theme=”Theme.Panel” 半透明,无标题,全屏
android:theme=”Theme.Light.Panel”平板风格显示
这些都是常见的系统主题,可以直接拿来用。如果想要自己特定的主题,还可以自定义主题。
3.定义自己的主题
①在res/values/style.xml 中定义自己想要的主题
<style name="MyTheme" parent="AppTheme">
<item name="android:windowIsTranslucent"> true </item>
<item name="android:windowBackground"> @android:color/transparent </item>
<item name="android:colorBackgroundCacheHint"> @null </item>
<item name="android:backgroundDimEnabled"> false </item>
<item name="android:windowAnimationStyle"> @null </item>
<item name="android:windowContentOverlay"> @null </item>
</style>
自定义的MyTheme主题就好了,可以在需要的地方来使用了。
自定义主题时用到了很多属性,来看看每个属性都代表什么意思:
<item name="colorPrimary"> @color/white </item> 应用的主要色调,actionBar默认使用该颜色,Toolbar导航栏的底色
<item name="colorPrimaryDark"> @color/white</item> 应用的主要暗色调,statusBarColor默认使用该颜色
<item name="colorAccent"> @color/colorAccent</item> 一般控件的选中效果默认采用该颜色,如CheckBox、RadioButton、SwitchCompat、ProcessBar等
<!-- 状态栏、顶部导航栏相关-->
<item name="android:statusBarColor"> #00000000</item> status bar的颜色
<item name="android:windowOverscan"> true</item> activity是否能在status bar底部绘制
<item name="android:windowTranslucentStatus ">true</item> 让status bar透明,相当于statusBarColor = transparent并且windowOverscan = true
<item name="android:windowLightStatusBar"> true</item> 改变status bar文字颜色, true黑色, false白色,API23可用
<item name="android:windowFullscreen"> true</item> 全屏显示,隐藏状态栏、导航栏、底部导航栏
<item name="windowNoTitle">true</item> 隐藏标题栏
<item name="android:navigationBarColor"> #E91E63</item> 底部虚拟导航栏颜色
<item name="android:windowTranslucentNavigation"> true</item> 让底部导航栏变半透明灰色,覆盖在Activity之上(默认false,activity会居于底部导航栏顶部),如果设为true,navigationBarColor 失效
<item name="android:windowBackground"> @drawable/ic_launcher_background</item>
<item name="android:windowBackground"> @color/light_purple</item> 设置window的背景可以设置@drawable或颜色引用@color,不能设置颜色值(#fffffff)。Window区域说明:Window涵盖整个屏幕显示区域,包括StatusBar的区域。当windowOverscan=false时,window的区域比Activity多出StatusBar,当windowOverscan=true时,window区域与Activity相同
<!-- 控件相关 -->
<item name="android:textAllCaps"> false</item> button上的文字是否全部大写(系统默认开)
<item name="android:textColor"> #B0C4DE</item> 默认Button、TextView的文字颜色
<item name="android:editTextColor"> #E6E6FA</item> 默认EditView输入框字体的颜色
<item name="android:textColorPrimaryDisableOnly"> #1C71A9</item> RadioButton、checkbox等控件的文字
<item name="android:textColorPrimary"> #FFFFFF</item> 应用的主要文字颜色,actionBar的标题文字默认使用该颜色
<item name="android:textColorSecondary"> #C1C1C1</item> 辅助的文字颜色,一般比textColorPrimary的颜色弱一点
<item name="android:colorControlActivated"> #FF7F50</item>控件选中时的颜色,默认使用colorAccent
<item name="android:colorControlHighlight"> #FF00FF</item> 控件按压时的色调
<item name="android:colorControlNormal"> #FFD700</item> CheckBox、RadioButton、SwitchCompat等默认状态的颜色
<item name="android:colorButtonNormal"> #1C71A9</item> 默认按钮的背景颜色
注意,在theme中设置Activity的属性无效, 请到AndroidManifest中Activity标签下设置。如:
<item name="android:launchMode"> singleTop</item>
<item name="android:screenOrientation"> landscape</item>
4.举例说明
实现要求:Activity D里有三个TextView分别为x、y、z,不同的入口进入的时候(例如:从A,B,C三个不同的Activity进入),D中的这三个TextView要显示不同的字体颜色。
最简单的办法就是,在进入Activity D之后对字体进行颜色设置。但是这样很麻烦,万一这个应用中有20个Activity,需要通过不同的入口显示不同的字体颜色,那需要每个Activity进入之后获取控件TextView,再一个个setTextColor……
这时候就可以使用主题了。
①首先需要自定义一个属性,在res路径下创建一个资源文件attr.xml。
②在attr.xml中定义三个属性,分别对应三个TextView的字体颜色,如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myTextColor1" format="color"/>
<attr name="myTextColor2" format="color"/>
<attr name="myTextColor3" format="color"/>
</resources>
③在需要切换TextView颜色的activity定义自己的主题theme。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme1" parent="AppTheme">
<item name="myTextColor1">@color/color1</item>
<item name="myTextColor2">@color/color1</item>
<item name="myTextColor3">@color/color1</item>
</style>
<style name="MyTheme2" parent="AppTheme">
<item name="myTextColor1">@color/color2</item>
<item name="myTextColor2">@color/color2</item>
<item name="myTextColor3">@color/color2</item>
</style>
<style name="MyTheme3" parent="AppTheme">
<item name="myTextColor1">@color/color3</item>
<item name="myTextColor2">@color/color3</item>
<item name="myTextColor3">@color/color3</item>
</style>
</resources>
④接下来在activity的布局文件中设置TextView的属性。
<TextView
android:id="@+id/tv_text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/myTextColor1"/>
<TextView
android:id="@+id/tv_text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/myTextColor2"/>
<TextView
android:id="@+id/tv_text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/myTextColor3"/>
⑤然后在不同地方进入Activity D的时候加上判断,不同的入口显示不同的样式。
onCreate方法中判断:
//切换不同的风格,必须在setContentView之前做
swith(themeType){
case 1:
setTheme(R.style,MyTheme1);
break;
case 2:
setTheme(R.style,MyTheme2);
break;
............
setContentView(R.layout.activity_main);
有些应用实时换皮肤的效果,其实就是利用修改主题来实现。