Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android學習之 換膚功能模塊的實現(二)

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

編輯:關於Android編程

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

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

\

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

\

本篇demo的換膚效果如下:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20141012/2014101209135434.png" width="360" height="650" alt="\"> \


\ \


主要的實現代碼在於:

1、SkinConfigManager.java

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

package com.ice.skininnerdemo;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * 皮膚配置管理<單例> 
* 封裝了 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中的 當前皮膚類型 值 * @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> data = new ArrayList>();
        int length = skinTypeImage.length;
        for(int i=0; i map = new HashMap();
            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

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

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




  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved