android换肤的方法非常多,如果不需要做成开放接口,只是自己的软件单纯支持换肤,或者在framework层做开发,需要根据系统设置修改app的皮肤,那么就可以使用theme来实现。其优势是维护和扩展方面,实现起来也很方便,只要使用xml文件提前定义好需要的皮肤,在项目中加入少量代码就可以实现。
1.添加变量,xml的变量一般定义在attrs.xml文件中,其位于res/values目录,需要手动添加该文件。这些变量可以定义成Drawable,color,dim等类型。如下:
<?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调用,如:
- public class Utils
- {
- private static int sTheme;
- public final static int THEME_DEFAULT = 0;
- public final static int THEME_WHITE = 1;
- public final static int THEME_BLUE = 2;
- /**
- * Set the theme of the Activity, and restart it by creating a new Activity
- * of the same type.
- */
- public static void changeToTheme(Activity activity, int theme)
- {
- sTheme = theme;
- activity.finish();
- activity.startActivity(new Intent(activity, activity.getClass()));
- }
- /** Set the theme of the activity, according to the configuration. */
- public static void onActivityCreateSetTheme(Activity activity)
- {
- switch (sTheme)
- {
- default:
- case 1:
- activity.setTheme(R.style.Theme_Translucent);
- break;
- case 2:
- activity.setTheme(R.style.Theme_Translucent2);
- break;
- case 3:
- activity.setTheme(R.style.Theme_Transparent);
- break;
- }
- }
- }
附录: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"
Android的ProgressBar样式:
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