C++ 代码

多种手机平台开发-----让我们跟苹果一起红起来。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Android应用如何实现换主题功能

Posted on 2011-09-13 16:25  蔡清华  阅读(2600)  评论(0编辑  收藏  举报

本文将介绍如何实现Android应用的换主题功能。假设一个简单的场景:有2套主题,一套绿色,一套黑色的。应用界面就一个按钮,每点击一下,按钮和背景都切换为不同的主题,如当前为黑色主题,下一次就为绿色主题,再下一次为黑色,以此类推。

打开Eclipse,新建三个Android工程项目,名字分别为BlackSkin、GreenSkin和MainSkin。BlackSkin和GreenSkin分别对应黑色、绿色主题资源,MainSkin为主应用。

BlackSkin
该工程下没有任何代码,只是在res\drawable目录下放置2张图片,一张黑色的背景,一张黑色的按钮图片。接着修改AndroidManifest.xml文件。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    package="net.toeach.blackskin"
    android:sharedUserId="net.toeach.MainSkin">
    
    <uses-sdk android:minSdkVersion="3" />

</manifest>

GreenSkin
与BlackSkin项目一样,该工程下也没有任何代码,只是在res\drawable目录下放置2张图片,一张绿色的背景,一张绿色的按钮图片。接着修改AndroidManifest.xml文件。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    package="net.toeach.greenskin"
    android:sharedUserId="net.toeach.mainskin">
    
    <uses-sdk android:minSdkVersion="3" />

</manifest>


我们知道Android给每个APK进程分配一个单独的用户空间,其manifest中的userid就是对应一个Linux用户的(Android 系统是基于Linux)。所以不同APK(用户)间互相访问数据默认是禁止的,但是它也提供了2种APK间共享数据的形式:
1. Share Preference. / Content Provider
APK可以指定接口和数据给任何其他APK读取,需要自己实现接口和Share的数据.

2. Shared User id
通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。所以默认就是可以互相访问任意数据。也可以配置成运行成不同的进程,同时可以访问其他APK的数据目录下的数据库和文件。就像访问本程序的数据一样。本文中的换主题功能就是通过这种方式来实现的。

MainSkin
该工程为主应用,我们新建立一个Activity类,叫MainActivity.java。代码如下:

public class MainActivity extends Activity {
  private LinearLayout showBg;
  private Button btn;
  private Context greenSkinContext = null;
  private Context blackSkinContext = null;
  int flag = 0;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    try {
     greenSkinContext = this.createPackageContext("net.toeach.greenskin", Context.CONTEXT_IGNORE_SECURITY);
     blackSkinContext = this.createPackageContext("net.toeach.blackskin", Context.CONTEXT_IGNORE_SECURITY);
    } catch (NameNotFoundException e) {
     e.printStackTrace();
    }
  
    showBg = (LinearLayout) findViewById(R.id.linear_layout_1);
    btn = (Button) findViewById(R.id.btn_change_skin);
    btn.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View v) {
       if (flag == 0) {
         //访问GreenSkin下的资源
         showBg.setBackgroundDrawable(greenSkinContext.getResources().getDrawable(R.drawable.bg));
         btn.setBackgroundDrawable(greenSkinContext.getResources().getDrawable(R.drawable.btn_normal));
         flag = 1;
       } else if (flag == 1) {
         //访问BlackSkin下的资源
         showBg.setBackgroundDrawable(blackSkinContext.getResources().getDrawable(R.drawable.bg));
         btn.setBackgroundDrawable(blackSkinContext.getResources().getDrawable(R.drawable.btn_normal));
         flag = 0;
       }//end of if
    });
  }//end of method
}//end of class
 
如果想要用自己的应用程序替代现在Android的Home(Launcher)可以在自己Activity的intent-filter中加入categroy.HOME
        <activity android:name=".MyHomeDemo"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>