Android學習之 換膚功能模組的實現<二>

來源:互聯網
上載者:User

標籤:android   換膚模組   

    在上篇中 主要有學習到皮膚資源內建到應用程式中 的方式實現換膚的 基本思路,本篇將繼續以上篇的思路學習 皮膚資源內建的方式實現換膚效果、但本篇側重於應用中換膚功能的代碼設計實現上!切換的皮膚資源位於assets下不同的皮膚資源檔夾中。

    本篇demo程式的代碼結構如下:

     

本篇實現換膚功能的代碼設計 UML類圖如下:


本篇demo的換膚效果如下:

      


      


主要的實現代碼在於:

1、SkinConfigManager.java  

作用:皮膚組態管理,封裝了SharedPreferences對選擇皮膚的序號儲存、以及根據皮膚類型鎖定assets下的皮膚資源。 詳細代碼如下:

package com.ice.skininnerdemo;import android.content.Context;import android.content.SharedPreferences;/** * 皮膚組態管理<單例> </br> * 封裝了 SharedPreferences 對象的儲存操作 * Created by ice on 14-10-9. */public class SkinConfigManager {    private static SkinConfigManager mSkinConfigManager;    public static final String SKINCONFIG = "SkinConfig";    public static final String CURSKINTYPEKEY = "curSkinTypeKey";    private static SharedPreferences mSharedPreferences;    private SkinConfigManager(Context context){        mSharedPreferences = context.getSharedPreferences(SKINCONFIG, 0);    }    public synchronized static SkinConfigManager getInstance(Context context) {        if (mSkinConfigManager == null) {            mSkinConfigManager = new SkinConfigManager(context);        }        return mSkinConfigManager;    }    /**     * 設定儲存當前選擇的皮膚類型值(int 類型值)到 SharedPreferences     * @param skinType  皮膚類型     */    public void setCurSkinType(int skinType){        SharedPreferences.Editor editor = mSharedPreferences.edit();        editor.putInt(CURSKINTYPEKEY, skinType);        editor.commit();    }    /**     * 獲得當前儲存在SharedPreferences中的 當前皮膚類型<CURSKINTYPE> 值     * @return     */    public int getCurSkinType(){        if (mSharedPreferences != null) {            return mSharedPreferences.getInt(CURSKINTYPEKEY, 0);        }        return 0;    }    /**     * 獲得assets檔案夾下面當前皮膚資源所對應的皮膚檔案夾名     * @return     */    public String getSkinFileName () {        String skinFileName = null;        switch (getCurSkinType()){            case 0:                // 預設的皮膚類型                break;            case 1:                skinFileName = "skin_blue";                break;            case 2:                skinFileName = "skin_orange";                break;            case 3:                skinFileName = "skin_red";                break;        }        return skinFileName;    }    public SharedPreferences getSkinConfigPreferences () {        return mSharedPreferences;    }}

2、SkinManager.java   

作用:皮膚資源管理員,用於擷取assets檔案下不同皮膚類型的圖片資源檔

詳細代碼如下:

package com.ice.skininnerdemo;import android.content.Context;import android.content.res.AssetManager;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.drawable.Drawable;import java.io.IOException;import java.io.InputStream;/** * Created by ice on 14-10-8. * 皮膚資源管理員<單例> */public class SkinManager {    private static SkinManager mSkinManager;    private AssetManager mAssetManager;    private SkinManager (Context context) {        this.mAssetManager = context.getAssets();    }    public synchronized static SkinManager getInstance(Context context){        if (mSkinManager == null) {            mSkinManager = new SkinManager(context);        }        return mSkinManager;    }    /**     * 根據皮膚檔案名稱 和 資源檔名 擷取Assets 裡面的皮膚資源Drawable對象     * @param skinFileName  皮膚檔案名稱     * @param fileName   資源檔名     * @return     */    public Drawable getSkinDrawable(String skinFileName, String fileName) {        Drawable drawable = null;        try {            InputStream inputStream = mAssetManager.open(skinFileName + "/" + fileName);            drawable = Drawable.createFromStream(inputStream, null);        } catch (IOException e) {            e.printStackTrace();        }        return drawable;    }    /**     * 根據皮膚檔案名稱 和 資源檔名 擷取Assets 裡面的皮膚資源Bitmap對象     * @param skinFileName     * @param fileName     * @return     */    public Bitmap getSkinBitmap(String skinFileName, String fileName){        Bitmap image = null;        try {            InputStream inputStream = mAssetManager.open(skinFileName + "/" + fileName);            image = BitmapFactory.decodeStream(inputStream);        } catch (IOException e) {            e.printStackTrace();        }        return image;    }}

3、SkinableActivity.java 

作用:換膚Activity抽象類別,如果說應用中某個Activiy有換膚的需求,那麼就繼承SkinableActivity吧!

它主要實現了OnSharedPreferenceChangeListener 監聽介面,並且註冊了SharedPreferences內容改變的事件監聽。

在監聽到SharedPreferences發生改變的同時回調changeSkin()抽象方法,該方法由SkinableActivity的子類具體實現UI上皮膚資源的更換。

詳細代碼如下:

package com.ice.skininnerdemo;import android.app.Activity;import android.content.SharedPreferences;/** * 換膚Activity抽象類別 * Created by ice on 14-10-8. */public abstract class SkinableActivity extends Activity implements SharedPreferences.OnSharedPreferenceChangeListener{    @Override    protected void onStart() {        super.onStart();        initSkin();    }    /**     *  初始化皮膚     */    private void initSkin() {        changeSkin();        // 註冊監聽,監聽換膚的通知        SkinConfigManager.getInstance(this).getSkinConfigPreferences()                .registerOnSharedPreferenceChangeListener(this);    }    /**     * sharedPreferences 內容發生改變時觸發     * @param sharedPreferences     * @param key sharedPreferences中的key值     */    @Override    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {        if (SkinConfigManager.CURSKINTYPEKEY.equals(key)) {            changeSkin();        }    }    @Override    protected void onStop() {        super.onStop();        SkinConfigManager.getInstance(this).getSkinConfigPreferences()                .unregisterOnSharedPreferenceChangeListener(this);    }    /**     * 更改設定皮膚,SkinableActivity子類必須要實現該方法 完成換膚過程     */    protected abstract void changeSkin();}

4、SkinSettingActivity.java

作用:皮膚設定Activity,繼承了SkinableActivity,實現了changeSkin()抽象方法,完成了皮膚設定UI上的皮膚更換。

(應用中其他需要換膚的Activity類似、主要在changeSkin()方法中實現介面的換膚需求)

詳細代碼如下:

package com.ice.skininnerdemo;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.AdapterView;import android.widget.GridView;import android.widget.SimpleAdapter;import android.widget.TextView;import java.util.ArrayList;import java.util.HashMap;import java.util.List;/** * 皮膚設定Activity * Created by ice on 14-10-10. */public class SkinSettingActivity extends SkinableActivity{    private static final String TAG = "SkinSettingActivity";    private GridView gv_skin_type;    private TextView tv_skin_cur;    private TextView tv_title_skin_setting;    private int[] skinTypeImage = new int[]{            R.drawable.overview_skin_default, R.drawable.overview_skin_blue,            R.drawable.overview_skin_orange, R.drawable.overview_skin_red    };    private int[] skinTypeName = new int[]{            R.string.skin_default, R.string.skin_blue,            R.string.skin_orange, R.string.skin_red    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_skin_setting);        initView();        bindEvent();    }    private void initView() {        tv_title_skin_setting = (TextView)findViewById(R.id.tv_title_skin_setting);        tv_skin_cur = (TextView)findViewById(R.id.tv_skin_cur);        gv_skin_type = (GridView)findViewById(R.id.gv_skin_type);        setGridViewAdapter(gv_skin_type);    }    private void setGridViewAdapter(GridView mGridView) {        List<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();        int length = skinTypeImage.length;        for(int i=0; i<length; i++){            HashMap<String,Object> map = new HashMap<String, Object>();            map.put("skinTypeImage", skinTypeImage[i]);            map.put("skinTypeName", getString(skinTypeName[i]));            data.add(map);        }        SimpleAdapter simpleAdapter = new SimpleAdapter(                this,                data,                R.layout.traffic_item,                new String[]{"skinTypeImage", "skinTypeName"},                new int[]{R.id.iv_traffic, R.id.tv_trafficName});        mGridView.setAdapter(simpleAdapter);    }    private void bindEvent() {        gv_skin_type.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {                tv_skin_cur.setText(skinTypeName[i]);                // 將當前選擇的皮膚對應的序號 儲存到 SharedPreferences 中                SkinConfigManager.getInstance(SkinSettingActivity.this).setCurSkinType(i);            }        });    }    @Override    protected void changeSkin() {        SkinConfigManager mSkinConfigManager = SkinConfigManager.getInstance(SkinSettingActivity.this);        String skinFileName = mSkinConfigManager.getSkinFileName();        Log.d(TAG, "changeSkin() 被執行 / skinFileName: " + skinFileName);        // 擷取當前正在使用的皮膚序號        int skinType = mSkinConfigManager.getCurSkinType();        tv_skin_cur.setText(skinTypeName[skinType]);        if(skinFileName != null){            Drawable drawable = SkinManager.getInstance(this).getSkinDrawable(skinFileName, "bg_title.9.png");            tv_title_skin_setting.setBackground(drawable);        } else {            tv_title_skin_setting.setBackgroundResource(R.drawable.bg_title);        }    }}


-- -- ok、本篇demo實現換膚效果的主要代碼、設計思路於此!小呂其實還想過另外一種皮膚資源的配置方式,

大體想法如下:

1、在assets檔案下下面建立一個皮膚資源的設定檔 如:skin.properties 或是 skin_configure.xml

2、所有的皮膚資源(圖片)將會放在res/drawable/下面,而什麼皮膚類型所對應的皮膚資源圖片將會在1中的skin.properties 或是 skin_configure.xml中 通過配置的方式引用。


當然  這隻是小呂目前的一個初步想法及設計思想、如果 看到這裡的您 如果還有其他實現換膚的設計思想、還希望大氣的給小呂留言、學習、和交流。


補充內容:本demo中 有關於擷取assets檔案中的.9格式圖片。

                   關於擷取assets下面的.9格式圖片問題,這裡是很有趣的,

                   該demo中assets下的.9格式圖片 都是先使用 AAPT 命令編譯處理後的,及被Android系統編譯過的。

                   那為什麼要這樣做呢?大家可以先自己研究下 或是 在網上搜尋答案、小呂后面有時間將會整理成部落格。


最後附上本篇demo的代碼<免下載積分>: http://download.csdn.net/detail/l416112167/8027581

-----------------

下篇  小呂將會學習與介紹第二種實現方式:  [皮膚資源與應用程式分離]




Android學習之 換膚功能模組的實現<二>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.