Android學習之 換膚功能模塊的實現

一、軟件換膚從功能上可以劃分三種:

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





發佈了71 篇原創文章 · 獲贊 16 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章