Android Theme和Style切换UI

android换肤的方法非常多,如果不需要做成开放接口,只是自己的软件单纯支持换肤,或者在framework层做开发,需要根据系统设置修改app的皮肤,那么就可以使用theme来实现。其优势是维护和扩展方面,实现起来也很方便,只要使用xml文件提前定义好需要的皮肤,在项目中加入少量代码就可以实现。

1.添加变量,xml的变量一般定义在attrs.xml文件中,其位于res/values目录,需要手动添加该文件。这些变量可以定义成Drawablecolordim等类型。如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="title_bg" format="reference" />

    <attr name="title_font_color" format="reference|color" />
    <attr name="title_font_size" format="dimension" />
    <attr name="title_icon_width" format="dimension" />
    <attr name="title_icon_height" format="dimension" />
    <attr name="context_bg" format="reference" />
    <attr name="item_font_color" format="reference|color" />
    <attr name="item_font_size" format="dimension" />
    <attr name="item_icon_width" format="dimension" />
    <attr name="item_icon_height" format="dimension" />
</resources>

2然后在res/values/style.xml文件中给这些变量赋值,不同的style可以给该变量赋不同的值,值的类型受attrs影响,如下:

<style name="AppTheme_Default">
        <item name="title_bg">@drawable/topbar_red</item>
        <item name="context_bg">@drawable/bg_red</item>
        <item name="title_font_color">#ffffffff</item>
        <item name="title_font_size">@dimen/Medium_text_size</item>
        <item name="title_icon_width">@dimen/title_icon_width</item>
        <item name="title_icon_height">@dimen/title_icon_height</item>
        
        <item name="item_font_color">#ff000000</item>
        <item name="item_font_size">@dimen/Medium_text_size</item>
        <item name="item_icon_width">@dimen/item_icon_width</item>
        <item name="item_icon_height">@dimen/item_icon_height</item>
    </style>

    <style name="AppTheme_Black">
        <item name="title_bg">@drawable/topbar_black</item>
        <item name="context_bg">@drawable/bg_purple</item>
        <item name="title_font_color">#ffffffff</item>
        <item name="title_font_size">@dimen/Medium_text_size</item>
        <item name="title_icon_width">@dimen/title_icon_width</item>
        <item name="title_icon_height">@dimen/title_icon_height</item>
        
        <item name="item_font_color">#ff000000</item>
         <item name="item_font_size">@dimen/Medium_text_size</item>
        <item name="item_icon_width">@dimen/item_icon_width</item>
        <item name="item_icon_height">@dimen/item_icon_height</item>
    </style>

    <style name="AppTheme_blue">
        <item name="title_bg">@drawable/topbar_blue</item>
        <item name="context_bg">@drawable/bg_blue</item>
        <item name="title_font_color">#ffffffff</item>
        <item name="title_font_size">@dimen/Medium_text_size</item>
        <item name="title_icon_width">@dimen/title_icon_width</item>
        <item name="title_icon_height">@dimen/title_icon_height</item>
        
        <item name="item_font_color">#ff000000</item>
        <item name="item_font_size">@dimen/Medium_text_size</item>
        <item name="item_icon_width">@dimen/item_icon_width</item>
        <item name="item_icon_height">@dimen/item_icon_height</item>
    </style>

    <style name="AppTheme_yellow">
        <item name="title_bg">@drawable/topbar_brown</item>
        <item name="context_bg">@drawable/bg_brown</item>
        <item name="title_font_color">#ffffffff</item>
        <item name="title_font_size">@dimen/Medium_text_size</item>
        <item name="title_icon_width">@dimen/title_icon_width</item>
        <item name="title_icon_height">@dimen/title_icon_height</item>
        
        <item name="item_font_color">#ff000000</item>
        <item name="item_font_size">@dimen/Medium_text_size</item>
        <item name="item_icon_width">@dimen/item_icon_width</item>
        <item name="item_icon_height">@dimen/item_icon_height</item>
    </style>

3.实现一个基础类调用这些style,其他的activity使用BaseActivity

public class BaseActivity extends Activity {
	public int mTheme = R.style.AppTheme_Default;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		/*
		if (savedInstanceState == null) {
			mTheme = PreferenceHelper.getTheme(this);
		} else {
			mTheme = savedInstanceState.getInt("theme");
		}
		*/
		setTheme(mTheme);
		super.onCreate(savedInstanceState);
	}

	@Override
	protected void onResume() {
		super.onResume();
		//if (mTheme != PreferenceHelper.getTheme(this)) {
		//	reload();
		//}
	}

	protected void reload() {
		Intent intent = getIntent();
		overridePendingTransition(0, 0);
		intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
		finish();
		overridePendingTransition(0, 0);
		startActivity(intent);
	}
}

也可以写一个类供需要换肤的activity调用,如:

  1. public class Utils  
  2. {  
  3.     private static int sTheme;  
  4.   
  5.     public final static int THEME_DEFAULT = 0;  
  6.     public final static int THEME_WHITE = 1;  
  7.     public final static int THEME_BLUE = 2;  
  8.   
  9.     /** 
  10.      * Set the theme of the Activity, and restart it by creating a new Activity 
  11.      * of the same type. 
  12.      */  
  13.     public static void changeToTheme(Activity activity, int theme)  
  14.     {  
  15.         sTheme = theme;  
  16.         activity.finish();  
  17.   
  18.         activity.startActivity(new Intent(activity, activity.getClass()));  
  19.     }  
  20.   
  21.     /** Set the theme of the activity, according to the configuration. */  
  22.     public static void onActivityCreateSetTheme(Activity activity)  
  23.     {  
  24.         switch (sTheme)  
  25.         {  
  26.         default:  
  27.         case 1:  
  28.           activity.setTheme(R.style.Theme_Translucent);  
  29.             break;  
  30.         case 2:  
  31.             activity.setTheme(R.style.Theme_Translucent2);  
  32.             break;  
  33.         case 3:  
  34.             activity.setTheme(R.style.Theme_Transparent);  
  35.             break;  
  36.         }  
  37.     }  


附录:attrs.xml用法:



1.reference:参考某一资源ID

    (1)属性定义:

           <declare-styleablename = "名称">

                  <attrname = "background" format = "reference" />

           </declare-styleable>

    (2)属性使用:

           <ImageView

                    android:layout_width= "42dip"

                    android:layout_height= "42dip"

                    android:background= "@drawable/图片ID"

                    />


2.color:颜色值。

    (1)属性定义:

           <declare-styleablename = "名称">

                  <attrname = "textColor" format = "color" />

           </declare-styleable>

    (2)属性使用:

           <TextView

                    android:layout_width= "42dip"

                    android:layout_height= "42dip"

                    android:textColor= "#00FF00"

                    />


 3.boolean:布尔值。

    (1)属性定义:

           <declare-styleablename = "名称">

               <attrname = "focusable" format = "boolean" />

           </declare-styleable>

    (2)属性使用:

           <Button

                  android:layout_width= "42dip"

                  android:layout_height= "42dip"

                  android:focusable= "true"

                   />

 

4.dimension:尺寸值。

     (1)属性定义:

            <declare-styleablename = "名称">

                  <attrname = "layout_width" format = "dimension" />

           </declare-styleable>

    (2)属性使用:

           <Button

                  android:layout_width= "42dip"

                  android:layout_height= "42dip"

                 />


 5.float:浮点值。

    (1)属性定义:

           <declare-styleablename = "AlphaAnimation">

                  <attrname = "fromAlpha" format = "float" />

                  <attrname = "toAlpha" format = "float" />

           </declare-styleable>

    (2)属性使用:

           <alpha

                  android:fromAlpha= "1.0"

                  android:toAlpha= "0.7"

                  />

 

6.integer:整型值。

    (1)属性定义:

           <declare-styleablename = "AnimatedRotateDrawable">

                  <attrname = "visible" />

                  <attrname = "frameDuration" format="integer" />

                  <attrname = "framesCount" format="integer" />

                  <attrname = "pivotX" />

                  <attrname = "pivotY" />

                  <attrname = "drawable" />

           </declare-styleable>

    (2)属性使用:

           <animated-rotate

                  xmlns:android= "http://schemas.android.com/apk/res/android"  

                  android:drawable= "@drawable/图片ID" 

                  android:pivotX= "50%"  

                  android:pivotY= "50%"  

                  android:framesCount= "12"  

                  android:frameDuration= "100"

                  />

 

7.string:字符串。

    (1)属性定义:

           <declare-styleablename = "MapView">

                  <attrname = "apiKey" format = "string" />

           </declare-styleable>

    (2)属性使用:

           <com.google.android.maps.MapView

                   android:layout_width= "fill_parent"

                   android:layout_height= "fill_parent"

                   android:apiKey= "0jOkQ80oD1JL9C6HAja99uGXCRiS2CGjKO_bc_g"

                   />


8.fraction:百分数。

     (1)属性定义:

           <declare-styleablename="RotateDrawable">

                  <attrname = "visible" />

                  <attrname = "fromDegrees" format = "float" />

                  <attrname = "toDegrees" format = "float" />

                  <attrname = "pivotX" format = "fraction" />

                  <attrname = "pivotY" format = "fraction" />

                  <attrname = "drawable" />

           </declare-styleable>


    (2)属性使用:

           <rotate

                xmlns:android= "http://schemas.android.com/apk/res/android" 

              android:interpolator= "@anim/动画ID"

                android:fromDegrees= "0" 

              android:toDegrees= "360"

                android:pivotX= "200%"

                android:pivotY= "300%" 

              android:duration= "5000"

                android:repeatMode= "restart"

                android:repeatCount= "infinite"

               />


9.enum:枚举值。

    (1)属性定义:

           <declare-styleablename="名称">

                  <attrname="orientation">

                         <enumname="horizontal" value="0" />

                         <enumname="vertical" value="1" />

                  </attr>           

           </declare-styleable>

    (2)属性使用:

           <LinearLayout

                   xmlns:android= "http://schemas.android.com/apk/res/android"

                   android:orientation= "vertical"

                   android:layout_width= "fill_parent"

                   android:layout_height= "fill_parent"

                   >

           </LinearLayout>


10.flag:位或运算。

     (1)属性定义:

            <declare-styleablename="名称">

                   <attrname="windowSoftInputMode">

                           <flagname = "stateUnspecified" value = "0" />

                           <flagname = "stateUnchanged" value = "1" />

                           <flagname = "stateHidden" value = "2" />

                           <flagname = "stateAlwaysHidden" value = "3" />

                           <flagname = "stateVisible" value = "4" />

                           <flagname = "stateAlwaysVisible" value = "5" />

                           <flagname = "adjustUnspecified" value = "0x00" />

                           <flagname = "adjustResize" value = "0x10" />

                           <flagname = "adjustPan" value = "0x20" />

                           <flagname = "adjustNothing" value = "0x30" />

                    </attr>        

            </declare-styleable>


     (2)属性使用:

           <activity

                  android:name= ".StyleAndThemeActivity"

                  android:label= "@string/app_name"

                  android:windowSoftInputMode= "stateUnspecified | stateUnchanged | stateHidden">

                  <intent-filter>

                         <actionandroid:name = "android.intent.action.MAIN" />

                         <categoryandroid:name = "android.intent.category.LAUNCHER" />

                  </intent-filter>

            </activity>

     注意:

     属性定义时可以指定多种类型值。

    (1)属性定义:

           <declare-styleablename = "名称">

                  <attrname = "background" format = "reference|color"/>

           </declare-styleable>

    (2)属性使用:

            <ImageView

                    android:layout_width= "42dip"

                    android:layout_height= "42dip"

                    android:background= "@drawable/图片ID|#00FF00"

                    />




android中的style部分属性值介绍

Android平台定义的主题样式:

android:theme="@android:style/Theme.Dialog"   将一个Activity显示为对话框模式

?android:theme="@android:style/Theme.NoTitleBar"  不显示应用程序标题栏
?android:theme="@android:style/Theme.NoTitleBar.Fullscreen"  
不显示应用程序标题栏,并全屏

?android:theme="@android:style/Theme.Light"  背景为白色
?android:theme="@android:style/Theme.Light.NoTitleBar"  
白色背景并无标题栏
?android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"  
白色背景,无标题栏,全屏

?android:theme="@android:style/Theme.Black"  背景黑色
?android:theme="@android:style/Theme.Black.NoTitleBar"  
黑色背景并无标题栏
?android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"    
黑色背景,无标题栏,全屏

?android:theme="@android:style/Theme.Wallpaper"  用系统桌面为应用程序背景
?android:theme="@android:style/Theme.Wallpaper.NoTitleBar"  
用系统桌面为应用程序背景,且无标题栏
?android:theme="@android:style/Theme.Wallpaper.NoTitleBar.Fullscreen"  
用系统桌面为应用程序背景,无标题栏,全屏

?android:theme="@android:style/Translucent"半透明效果
?android:theme="@android:style/Theme.Translucent.NoTitleBar"  
半透明并无标题栏
?android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"  
半透明效果,无标题栏,全屏
?android:theme="@android:style/Theme.Panel"

Android
平台定义了三种字体大小:

"?android:attr/textAppearanceLarge"
"?android:attr/textAppearanceMedium"
"?android:attr/textAppearanceSmall"

新版本似乎添加了一个巨大字体Huge

Android字体颜色:

android:textColor="?android:attr/textColorPrimary"
android:textColor="?android:attr/textColorSecondary"
android:textColor="?android:attr/textColorTertiary"
android:textColor="?android:attr/textColorPrimaryInverse"
android:textColor="?android:attr/textColorSecondaryInverse"

AndroidProgressBar样式:

style="?android:attr/progressBarStyleHorizontal"
style="?android:attr/progressBarStyleLarge"
style="?android:attr/progressBarStyleSmall"
style="?android:attr/progressBarStyleSmallTitle"

 

分隔符

横向:

<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider"/>


纵向:

<Viewandroid:layout_width="1dip"
android:layout_height="fill_parent"
android:background="?android:attr/listDivider"/>

 

CheckBox样式  

style="?android:attr/starStyle"


类似标题栏效果的TextView
style="?android:attr/listSeparatorTextViewStyle"

其它有用的样式
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingRight="?android:attr/scrollbarSize"
style="?android:attr/windowTitleBackgroundStyle"
style="?android:attr/windowTitleStyle"
android:layout_height="?android:attr/windowTitleSize"
android:background="?android:attr/windowBackground"

 

修改Activity的标题栏样式

如在styles.xml中增加
<resources> 
    <style name="AutoWindowTitleBackground"> 
        <itemname="android:background">#778899</item> 
    </style> 
    <style name="autoWindowTitlebar" parent="android:Theme"> 
        <itemname="android:windowTitleSize">32dp</item>
        <itemname="android:windowTitleBackgroundStyle">@style/AutoWindowTitleBackground</item>
    </style> 
</resources>

接着再修改AndroidManifest.xml文件,找到要自定义标题栏的Activity,添加上android:theme值,比如:
<activity android:name=".MainActivity" android:theme="@style/autoWindowTitlebar">

 

去掉所有Activity界面的标题栏
修改AndroidManifest.xml

application标签中添加android:theme=”@android:style/Theme.NoTitleBar”



参考:

http://www.cnblogs.com/bluestorm/archive/2013/03/20/2971742.html

http://blog.sina.com.cn/s/blog_62ef2f14010105vi.html

http://www.krislq.com/2013/04/android_class_change_skin/

http://blog.csdn.net/wsscy2004/article/details/7562909


Android Theme和Style切换UI,布布扣,bubuko.com

Android Theme和Style切换UI

上一篇:如何在Ubuntu 14.04中配置PXE服务器


下一篇:13 个 Mongodb GUI 可视化管理工具,总有一款适合你