一、軟件換膚從功能上可以劃分三種:
1) 軟件內置多個皮膚,不可由用戶增加或修改;
2) 官方提供皮膚供下載,用戶可以使用下載的皮膚;
3) 官方提供皮膚製作工具或方法,用戶可自制皮膚。
二、軟件換膚從實現上來可以劃分二種:
1) 皮膚內置到應用程序中;
2) 皮膚資源與應用程序分離;
三、本篇將先學習第一種相對非常簡單的實現方式一:[皮膚資源內置到應用程序中]
該方式的主要思路:
1. 把幾套皮膚[作爲應用背景的圖片資源]放在res/drawable目錄裏,然後用SharedPreferences來記錄當前皮膚的資源id.然後在程序啓動時加載Activity背景。
2. 主要的實現在皮膚設置管理器SkinSettingManager類中. 將皮膚資源的ID加入集合中. 由該類統一調度皮膚更換,如初始化皮膚,獲取當前皮膚符號以及具體的對應資源的更換皮膚.
下面將以一個小demo程序來介紹具體的代碼實現:
1) 首先程序運行效果圖如下:
2) 佈局文件:src\main\res\layout\activity_skin_main.xml
【我這裏使用的是Android Studio, 項目結構與Eclipse不一樣】
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.ice.skininnerdemo.SkinInnerDemoActivity">
<CheckBox
android:id="@+id/cb_skin1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/skin_default"/>
<!-- 分割線 -->
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginTop="10dp"
android:background="@drawable/line_shape" />
<CheckBox
android:id="@+id/cb_skin2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/skin_morning" />
<!-- 分割線 -->
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginTop="10dp"
android:background="@drawable/line_shape" />
<CheckBox
android:id="@+id/cb_skin3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/skin_night" />
<!-- 分割線 -->
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginTop="10dp"
android:background="@drawable/line_shape" />
</LinearLayout>
裏面有個 Shpae繪製的 分割線drawable資源文件:@drawable/line_shape ,內容如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#DCDCDC" />
<size android:height="1dp" android:width="1dp" />
</shape>
3) 重要的皮膚設置管理器:SkinSettingManager.java
package com.ice.skininnerdemo;
import android.app.Activity;
import android.content.SharedPreferences;
/**
* Copy by http://blog.csdn.net/t12x3456/article/details/7933382
*/
public class SkinSettingManager {
public final static String SKIN_PREF = "skinSetting";
public SharedPreferences skinSettingPreference;
/** 初始化3種皮膚資源 */
private int[] skinResources = { R.drawable.dusk,
R.drawable.morning, R.drawable.night
};
private Activity mActivity;
public SkinSettingManager(Activity activity) {
this.mActivity = activity;
skinSettingPreference = mActivity.getSharedPreferences(SKIN_PREF, 3);
}
/**
* 獲取當前程序的皮膚序號
*
* @return
*/
public int getSkinType() {
String key = "skin_type";
return skinSettingPreference.getInt(key, 0);
}
/**
* 把皮膚序號寫到全局設置裏去
*
* @param j
*/
public void setSkinType(int j) {
SharedPreferences.Editor editor = skinSettingPreference.edit();
String key = "skin_type";
editor.putInt(key, j);
editor.commit();
}
/**
* 獲取當前皮膚的背景圖資源id
*
* @return
*/
public int getCurrentSkinRes() {
int skinLen = skinResources.length;
int getSkinLen = getSkinType();
if(getSkinLen >= skinLen){
getSkinLen = 0;
}
return skinResources[getSkinLen];
}
/**
* 選擇皮膚資源
* @param skinTypeIndex 皮膚資源索引
*/
public void selectSkinType(int skinTypeIndex){
setSkinType(skinTypeIndex);
mActivity.getWindow().setBackgroundDrawable(null);
try {
mActivity.getWindow().setBackgroundDrawableResource(getCurrentSkinRes());
} catch (Exception e){
e.printStackTrace();
}
}
/**
* 用於初始化皮膚
*/
public void initSkins(){
mActivity.getWindow().setBackgroundDrawableResource(getCurrentSkinRes());
}
}
4) 程序Activity主界面: SkinInnerDemoActivity。
package com.ice.skininnerdemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.CompoundButton;
public class SkinInnerDemoActivity extends Activity {
private SkinSettingManager mSkinSettingManager;
private CheckBox cb_skin1, cb_skin2, cb_skin3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_skin_main);
mSkinSettingManager = new SkinSettingManager(this);
initView();
bindEvent();
}
private void initView() {
cb_skin1 = (CheckBox) findViewById(R.id.cb_skin1);
cb_skin2 = (CheckBox) findViewById(R.id.cb_skin2);
cb_skin3 = (CheckBox) findViewById(R.id.cb_skin3);
// 初始化默認皮膚
mSkinSettingManager.initSkins();
cb_skin1.setChecked(true);
}
private void bindEvent() {
SkinCheckedChangeListener skinCheckListener = new SkinCheckedChangeListener();
cb_skin1.setOnCheckedChangeListener(skinCheckListener);
cb_skin2.setOnCheckedChangeListener(skinCheckListener);
cb_skin3.setOnCheckedChangeListener(skinCheckListener);
}
/**
* CheckBox Check選中變化事件監聽類
*/
class SkinCheckedChangeListener implements CompoundButton.OnCheckedChangeListener{
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
switch (compoundButton.getId()) {
case R.id.cb_skin1:
if (checked) {
// 選中狀態
mSkinSettingManager.selectSkinType(0);
cb_skin2.setChecked(false);
cb_skin3.setChecked(false);
}
break;
case R.id.cb_skin2:
if (checked) {
// 選中狀態
mSkinSettingManager.selectSkinType(1);
cb_skin1.setChecked(false);
cb_skin3.setChecked(false);
}
break;
case R.id.cb_skin3:
if (checked) {
// 選中狀態
mSkinSettingManager.selectSkinType(2);
cb_skin1.setChecked(false);
cb_skin2.setChecked(false);
}
break;
}
}
}
}
到這裏 主要介紹、學習了第一種實現換膚的方式:皮膚資源內置到應用程序中的換膚、這種方式一般適用於小型、對換膚圖片背景資源要求不高的情況、不支持下載皮膚、自定義皮膚、只能更換應用內置的幾種皮膚效果。本demo程序也只是一個簡單、粗暴、單界面的展示、重點是掌握內置換膚的思路。
++++++++++++++++++++
本篇學習參考於:http://blog.csdn.net/t12x3456/article/details/7933382