android应用程序皮肤

皮肤内置在程序里面的!其实可以不用我这么复杂的,直接每次换肤更改图片资源就可以。

 

那还是写上我的东西。

 

此处的xml借鉴郑涛的一篇关于xml详解一的一篇文章,写得很不错,大家也可以看看!

 

http://www.cnblogs.com/zhengtao/articles/1924940.html

 

基本思路是,每个控件在布局中写资源是drawable中的一个xml文件

 

而这个xml文件给每个控件分了4个level的图片

 

在程序中直接修改level就可以达到修改控件的图片资源!

 

贴上一个 button的buttonskin1.xml

 

 

<?xml version="1.0" encoding="utf-8"?>

<level-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:maxLevel="1" android:drawable="@drawable/button11" />

    <item android:maxLevel="2" android:drawable="@drawable/button21" />

    <item android:maxLevel="3" android:drawable="@drawable/button31" />

    <item android:maxLevel="4" android:drawable="@drawable/button41" />

</level-list>

 

在布局文件里面 设置button的资源时候直接像引用图片那样android:background = "@drawable/buttonskin1"

 

程序里面通过修改level就可以修改它的bg button1.getBackground().setLevel(level);

 

之所以这样写是在 再添加其他的主题时候只需要在button里面再添加个level就可以 再弄个监听器触发一下

 

布局文件main.xml:

 

 

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

<LinearLayout

android:id = "@+id/linearlayout1"

android:layout_width = "fill_parent"

android:layout_height = "wrap_content"

android:layout_alignParentTop = "true">

<Button

android:id = "@+id/button1"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/buttonskin1"/>

<Button

android:id = "@+id/button2"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/buttonskin2"/>

<Button

android:id = "@+id/button3"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/buttonskin3"/>

<Button

android:id = "@+id/button4"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/buttonskin4"/>

</LinearLayout>

 

<LinearLayout

android:id = "@+id/linearlayout2"

android:layout_width = "fill_parent"

android:layout_height = "wrap_content"

android:layout_alignParentBottom = "true">

<Button

android:id = "@+id/button5"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/buttonskin5"/>

<Button

android:id = "@+id/button6"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/buttonskin6"/>

<Button

android:id = "@+id/button7"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/buttonskin7"/>

<Button

android:id = "@+id/button8"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/buttonskin8"/>

</LinearLayout>

<ImageView

android:id = "@+id/image"

android:layout_width = "fill_parent"

android:layout_height = "wrap_content"

android:layout_below = "@id/linearlayout1"

android:layout_above = "@id/linearlayout2"

android:src = "@drawable/imageskin"/>

 

</RelativeLayout>


主题程序:skin.java:

package com.bkship.skin;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class Skin extends Activity {
    private Button button1;
    private Button button2;
    private Button button3;
    private Button button4;
    private Button button5;
    private Button button6;
    private Button button7;
    private Button button8;
    private ImageView image;
    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        button1 = (Button)findViewById(R.id.button1);
        button2 = (Button)findViewById(R.id.button2);
        button3 = (Button)findViewById(R.id.button3);
        button4 = (Button)findViewById(R.id.button4);
        button5 = (Button)findViewById(R.id.button5);
        button6 = (Button)findViewById(R.id.button6);
        button7 = (Button)findViewById(R.id.button7);
        button8 = (Button)findViewById(R.id.button8);
        image = (ImageView)findViewById(R.id.image);
        button5.setOnClickListener(onClick);
        button6.setOnClickListener(onClick);
        button7.setOnClickListener(onClick);
        button8.setOnClickListener(onClick);
    }

OnClickListener onClick = new OnClickListener(){
public void onClick(View v) {
int id = v.getId();
switch(id){
case R.id.button5:
changeSkinLevel(1);
break;
case R.id.button6:
changeSkinLevel(2);
break;
case R.id.button7:
changeSkinLevel(3);
break;
case R.id.button8:
changeSkinLevel(4);
break;
default:
break;
}
}
};
private void changeSkinLevel(int level) {
button1.getBackground().setLevel(level);
button2.getBackground().setLevel(level);
button3.getBackground().setLevel(level);
button4.getBackground().setLevel(level);
button5.getBackground().setLevel(level);
button6.getBackground().setLevel(level);
button7.getBackground().setLevel(level);
button8.getBackground().setLevel(level);
image.getDrawable().setLevel(level);
}
}

再最下面的4个按钮添加监听器 分别对应4中皮肤!

通过网上流传的sharedUserId实现 不同程序间的资源共享

 

 

这种就是皮肤分离,皮肤是个单独的apk单独从网上下下来安装后,供主程序调用资源

 

 

大家可以参考下雨辰专栏写的一篇文章:

 

 

http://blog.csdn.net/suiyc/archive/2011/04/17/6329212.aspx

 

 

QQ,墨迹天气,搜狗输入法貌似都是这种方式实现的

 

 

在主程序,皮肤程序的manifest中都添加同一个sharedUserId,这个应该是随便你写,只要共享工程的一样

 

 

android:sharedUserId=com.bkship

 

 

 

皮肤工程比较简单创建一个后就是在manifest中添加sharedUserId 然后在drawable中放进你的图片就可以

 

 

 

主程序里面通过下面方法来调用皮肤工程

 

 

 

 

Context ctx = MySkin.this.createPackageContext(

 

 

 

           “com.bkship.skin1”,Context.CONTEXT_IGNORE_SECURITY); 

 

 

 

 

button1.setBackgroundDrawable(ctx.getResources().getDrawable(R.drawable.button1));

 

 

 

 

此处的com.bkship.skin1为你皮肤工程的包名。

 

 

 

而且这里要注意的就是你要替换的资源的名字 必须跟 主程序里面的资源名字一致

 

 

 

这可能也是为什么QQ,墨迹天气,搜狗输入法 自身只带一套皮肤的原因。

 

 

 

因为主程序带多套皮肤的话,必然是不同的名字,那皮肤工程没法去跟替换的资源同名,因为你替换时候

 

 

 

当前不定是哪个资源呢,当然这也仅仅是我自己的理解啦。

 

 

 

布局跟我上一篇的一样

 

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

<LinearLayout

android:id = "@+id/linearlayout1"

android:layout_width = "fill_parent"

android:layout_height = "wrap_content"

android:layout_alignParentTop = "true">

<Button

android:id = "@+id/button1"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/button1"/>

<Button

android:id = "@+id/button2"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/button2"/>

<Button

android:id = "@+id/button3"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/button3"/>

<Button

android:id = "@+id/button4"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/button4"/>

</LinearLayout>

 

<LinearLayout

android:id = "@+id/linearlayout2"

android:layout_width = "fill_parent"

android:layout_height = "wrap_content"

android:layout_alignParentBottom = "true">

<Button

android:id = "@+id/button5"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/button5"/>

<Button

android:id = "@+id/button6"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/button6"/>

<Button

android:id = "@+id/button7"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/button7"/>

<Button

android:id = "@+id/button8"

android:layout_width = "wrap_content"

android:layout_height = "wrap_content"

android:background = "@drawable/button8"/>

</LinearLayout>

<ImageView

android:id = "@+id/image"

android:layout_width = "fill_parent"

android:layout_height = "wrap_content"

android:layout_below = "@id/linearlayout1"

android:layout_above = "@id/linearlayout2"

android:background = "@drawable/bg"/>

 

</RelativeLayout>

 

 

 

 

 

下面是主体程序 :

 

 

 

 

package com.bkship.myskin;

 

import android.app.Activity;

import android.content.Context;

import android.content.pm.PackageManager.NameNotFoundException;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ImageView;

 

public class MySkin extends Activity {

    /** Called when the activity is first created. */

 

    private Button button1;

    private Button button2;

    private Button button3;

    private Button button4;

    private Button button5;

    private Button button6;

    private Button button7;

    private Button button8;

    private ImageView image;

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

 

        button1 = (Button)findViewById(R.id.button1);

button2 = (Button)findViewById(R.id.button2);

button3 = (Button)findViewById(R.id.button3);

button4 = (Button)findViewById(R.id.button4);

button5 = (Button)findViewById(R.id.button5);

button6 = (Button)findViewById(R.id.button6);

button7 = (Button)findViewById(R.id.button7);

button8 = (Button)findViewById(R.id.button8);

image = (ImageView)findViewById(R.id.image);

button5.setOnClickListener(onClick);

button6.setOnClickListener(onClick);

button7.setOnClickListener(onClick);

button8.setOnClickListener(onClick);

 

    }

 

OnClickListener onClick = new OnClickListener(){

 

@Override

public void onClick(View v) {

Context ctx = null;

int id = v.getId();

String skinPackage = null;

switch (id ) {

case R.id.button5:

skinPackage = "com.bkship.myskin";

break;

case R.id.button6:

skinPackage = "com.bkship.myskin1";

break;

case R.id.button7:

skinPackage = "com.bkship.myskin2";

break;

case R.id.button8:

skinPackage = "com.bkship.myskin3";

break;

default:

break;

}

 

try {

ctx = MySkin.this.createPackageContext(

skinPackage,

Context.CONTEXT_IGNORE_SECURITY);

Log.e("", "ctx");

} catch (NameNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

Log.e("", "ctx is null");

}

button1.setBackgroundDrawable(ctx.getResources().getDrawable(

R.drawable.button1));

button2.setBackgroundDrawable(ctx.getResources().getDrawable(

R.drawable.button2));

button3.setBackgroundDrawable(ctx.getResources().getDrawable(

R.drawable.button3));

button4.setBackgroundDrawable(ctx.getResources().getDrawable(

R.drawable.button4));

button5.setBackgroundDrawable(ctx.getResources().getDrawable(

R.drawable.button5));

button6.setBackgroundDrawable(ctx.getResources().getDrawable(

R.drawable.button6));

button7.setBackgroundDrawable(ctx.getResources().getDrawable(

R.drawable.button7));

button8.setBackgroundDrawable(ctx.getResources().getDrawable(

R.drawable.button8));

image.setBackgroundDrawable(ctx.getResources().getDrawable(

R.drawable.bg));

}

};

}

 

 

 

 

将主程序跟三个皮肤程序 打包奉上!

 

 

对了 要运行看效果的话 得将皮肤包三个先在机子上跑一下。

 

 

要主程序调用皮肤工程 得皮肤工程安装了才行

 

 

同时这种情况会导致安装了好多皮肤后你的程序列表里面会多好多皮肤程序,

 

 

可以通过下面的代码将其隐藏,只能在管理应用程序那里能看到

 

 

在要隐藏的皮肤工程的manifest里面的intentfilter中去掉这句

 

 

<category android:name="android.intent.category.LAUNCHER"></category>

 

 

这句话就是说 让我们的应用程序在launcher里启动起来,

 

 

不写它就是不让在那里启动,当然也就看不到我们的应用程序的图标了。

 

 

 

关于在launcher中不显示,这块,借鉴于cat_fang 的blog :

 

 

http://archive.cnblogs.com/a/2068309/



以上转自:http://bkship.iteye.com/blog/1104573



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值