Android学习之 换肤功能模块的实现<一>

本文介绍了Android应用中换肤功能的三种类型和两种实现方式,重点讲解了皮肤资源内置到应用程序中的实现方法。通过在res/drawable目录下放置皮肤图片,并使用SharedPreferences存储当前皮肤ID,结合SkinSettingManager类进行皮肤管理,实现启动时加载Activity背景的动态换肤效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、软件换肤从功能上可以划分三种:

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.youkuaiyun.com/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.youkuaiyun.com/t12x3456/article/details/7933382





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值