MyException - 我的异常网
当前位置:我的异常网» Android » Android怎么实现皮肤的定制与更换

Android怎么实现皮肤的定制与更换

www.MyException.Cn  网友分享于:2013-07-31  浏览:76次
Android如何实现皮肤的定制与更换

本篇主要是一个demo,该切换主题的demo里面一共实现了两个功能,其一,搜索已经安装的皮肤,其二,应用安装的皮肤。

主项目包名为org.leepood.skindemo,主题项目的包名为org.leepood.skin.blue,org.leepood.skin.red,等等,只要前缀是org.leepood.skin.就行。

首先是查找已安装主题的代码:

01.package org.leepood.skindemo;  
02. 
03.import java.util.ArrayList;  
04.import java.util.List;  
05. 
06.import android.app.Activity;  
07.import android.app.ProgressDialog;  
08.import android.content.Context;  
09.import android.content.Intent;  
10.import android.content.SharedPreferences;  
11.import android.content.pm.PackageInfo;  
12.import android.content.pm.PackageManager;  
13.import android.content.pm.PackageManager.NameNotFoundException;  
14.import android.content.res.Resources;  
15.import android.os.Bundle;  
16.import android.os.Handler;  
17.import android.os.Message;  
18.import android.view.ContextMenu;  
19.import android.view.LayoutInflater;  
20.import android.view.MenuItem;  
21.import android.view.View;  
22.import android.view.ViewGroup;  
23.import android.view.ContextMenu.ContextMenuInfo;  
24.import android.view.View.OnCreateContextMenuListener;  
25.import android.widget.BaseAdapter;  
26.import android.widget.ImageView;  
27.import android.widget.ListView;  
28.import android.widget.TextView;  
29.import android.widget.Toast;  
30.import android.widget.AdapterView.AdapterContextMenuInfo;  
31. 
32.public class Main extends Activity implements SharedPreferences.OnSharedPreferenceChangeListener{  
33. 
34.    private ListView listview;  
35.    private Context c;  
36.    private Handler mHandler;  
37.    private ProgressDialog pDialog;  
38.    private SkinAdapter adapter;  
39.    private SharedPreferences sp;  
40.    static final int MESSAGE_SEARCHED_SKIN=0;  
41.    static final int MESSAGE_SEARCHING_SKIN=MESSAGE_SEARCHED_SKIN+1;  
42.    static final int MESSAGE_SEARCHED_SKIN_FOR_NONTHING=MESSAGE_SEARCHING_SKIN+1;  
43. 
44.    @Override 
45.    protected void onCreate(Bundle savedInstanceState) {  
46. 
47.        super.onCreate(savedInstanceState);  
48.        setContentView(R.layout.main);  
49.        init();  
50.        pDialog.show();  
51.        new Thread(serachSkin).start();  
52. 
53.    }  
54. 
55.    private void init()  
56.    {  
57. 
58.        c=this;  
59.        mHandler=new Handler(){  
60. 
61.            @Override 
62.            public void handleMessage(Message msg) {  
63.                switch(msg.what)  
64.                {  
65.                case MESSAGE_SEARCHED_SKIN:  
66.                    ArrayList  
67. skins=(ArrayList  
68.) msg.obj;//获取skins  
69.                    adapter=new SkinAdapter(c, skins);  
70.                    listview.setAdapter(adapter);  
71.                    Toast.makeText(c, "查找到已经安装的皮肤", 1).show();  
72.                    pDialog.dismiss();  
73.                    break;  
74.                case MESSAGE_SEARCHED_SKIN_FOR_NONTHING:  
75.                    Toast.makeText(c, "未查找到任何皮肤", 1).show();  
76.                    pDialog.dismiss();  
77.                }  
78.            }  
79. 
80.        };  
81.        sp=this.getSharedPreferences("config",Context.MODE_WORLD_WRITEABLE);  
82.        sp.registerOnSharedPreferenceChangeListener(this);  
83. 
84.        listview=(ListView) findViewById(R.id.list);  
85.        listview.setItemsCanFocus(false);  
86.        listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE);  
87. 
88.        pDialog=new ProgressDialog(this);  
89.        pDialog.setMessage("正在查找已经安装的皮肤");  
90. 
91.        listview.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {  
92. 
93.            public void onCreateContextMenu(ContextMenu menu, View v,  
94.                    ContextMenuInfo menuInfo) {  
95.                menu.add("使用该主题");  
96. 
97.            }  
98.        });  
99. 
100.    }  
101. 
102.    private Runnable serachSkin =new Runnable(){  
103. 
104.        public void run() {  
105.            PackageManager manager=c.getPackageManager();  
106.            List  
107. packages=manager.getInstalledPackages(PackageManager.PERMISSION_GRANTED);  
108. 
109.            ArrayList  
110. skins=new ArrayList  
111.();  
112.            for(PackageInfo info:packages)  
113.            {  
114.                //System.out.println(info.packageName); 
115.                if(info.packageName.startsWith("org.leepood.skin."))  
116.                {  
117.                    skins.add(info);  
118.                }  
119.            }  
120.            if(skins.size()>0)  
121.            {  
122.                Message msg=mHandler.obtainMessage();  
123.                msg.obj=skins;  
124.                msg.what=MESSAGE_SEARCHED_SKIN;  
125.                mHandler.sendMessage(msg);  
126.            }  
127.            else 
128.            {  
129.                mHandler.sendEmptyMessage(MESSAGE_SEARCHED_SKIN_FOR_NONTHING);  
130.            }  
131. 
132.        }  
133. 
134.    };  
135.    private class SkinAdapter extends BaseAdapter  
136.    {  
137. 
138.        LayoutInflater mInflater;  
139.        ArrayList  
140. datas;  
141.        PackageManager manager;  
142.        public SkinAdapter(Context c,ArrayList  
143. datas)  
144.        {  
145. 
146.            this.datas=datas;  
147.             mInflater=LayoutInflater.from(c);  
148.             manager=c.getPackageManager();  
149.        }  
150. 
151.        public int getCount() {  
152. 
153.            return datas.size();  
154.        }  
155. 
156.        public Object getItem(int position) {  
157. 
158.            return datas.get(position);  
159.        }  
160. 
161.        public long getItemId(int position) {  
162. 
163.            return 0;  
164.        }  
165. 
166.        public View getView(int position, View convertView, ViewGroup parent) {  
167. 
168.            if(convertView==null)  
169.            {  
170.                convertView=mInflater.inflate(R.layout.skin_item, null);  
171.            }  
172.            ImageView icon=(ImageView) convertView.findViewById(R.id.skin_icon);  
173.            TextView  skin_name=(TextView) convertView.findViewById(R.id.skin_name);  
174.            PackageInfo info=datas.get(position);  
175.            icon.setImageDrawable(info.applicationInfo.loadIcon(manager));  
176.            skin_name.setText(info.applicationInfo.loadLabel(manager));  
177.            return convertView;  
178.        }  
179. 
180.    }  
181. 
182.    public void onThemeChanged(String newThemePackageName) {  
183.        try {  
184. 
185.            Context themeContext=this.createPackageContext(newThemePackageName, CONTEXT_IGNORE_SECURITY);  
186.            Resources res=themeContext.getResources();  
187.            setControlsStyle(res);  
188. 
189.        } catch (NameNotFoundException e) {  
190. 
191.            e.printStackTrace();  
192.        }  
193. 
194.    }  
195. 
196.    private void setControlsStyle(Resources res)  
197.    {  
198.        listview.setBackgroundColor(res.getColor(R.color.ListView_bg));  
199. 
200.    }  
201. 
202.    @Override 
203.    public boolean onContextItemSelected(MenuItem item) {  
204.        AdapterContextMenuInfo menuInfo=(AdapterContextMenuInfo)item.getMenuInfo();  
205.        PackageInfo info=(PackageInfo) adapter.getItem(menuInfo.position);  
206. 
207.        sp.edit().putString("themePackage", info.packageName).commit();  
208.        return super.onContextItemSelected(item);  
209.    }  
210. 
211.    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,  
212.            String key) {  
213.        System.out.println("themeChange");  
214.        onThemeChanged(sharedPreferences.getString(key, ""));  
215. 
216.    }  
217. 
218.}

这段代码的含义就是去查找系统中安装的包名,若以org.leepood.skin.开头则说明该包为主题包,将其加入listview中显示出来。代码中使用了多线程避免时间过长堵塞UI。程序将当前主题配置保存在SharedPreference中,为SharedPreference注册了一个监听函数,当其值发生改变时自动调用新的样式。当然,这只是个demo而已,一开始加载Activity没有去读取主题,这个可以由大家自己去实现。

Android实现主题切换机制2
昨天花了点时间实现了主题的切换,但是里面还是不够灵活,回去想了想可以用继承和回调函数来进一步灵活更改主题,现在记录下我的实现办法
首先一个自定义类ThemeActivity继承自Activity,这个类是以后所有Activity的父类,在这个类里面定义了一个接口

public interface OnThemeChangedListener
{
public void onChanged(String newThemePackageName);

}
接下来,首先是要给ThemeActivity注册一个主题切换的listener,代码如下:

public void setOnThemeChangedListener(OnThemeChangedListener listener)
{
this.listener=listener;
}
然后就是注册一个SharedPreference来监听xml的变化,当发生改变的时候自动去调用listener.onChanged方法,将新的主题包名传递过去,代码如下:

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if(key.equals("themePackage"))
{
listener.onChanged(sp.getString("themePackage", ""));
}

}
接着在继承于ThemeActivity的子类里面首先是setOnThemeChangedListener.接着用一个匿名内部类搞定。

 

 

:博客涉及的源码请在千寻资源库:www.qxzyk.com 下载获取,谢谢支持。

文章评论

10个调试和排错的小建议
10个调试和排错的小建议
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
旅行,写作,编程
旅行,写作,编程
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
程序员和编码员之间的区别
程序员和编码员之间的区别
漫画:程序员的工作
漫画:程序员的工作
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
我是如何打败拖延症的
我是如何打败拖延症的
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
程序员都该阅读的书
程序员都该阅读的书
编程语言是女人
编程语言是女人
如何成为一名黑客
如何成为一名黑客
程序员应该关注的一些事儿
程序员应该关注的一些事儿
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
代码女神横空出世
代码女神横空出世
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
一个程序员的时间管理
一个程序员的时间管理
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
总结2014中国互联网十大段子
总结2014中国互联网十大段子
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
鲜为人知的编程真相
鲜为人知的编程真相
每天工作4小时的程序员
每天工作4小时的程序员
 程序员的样子
程序员的样子
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
程序员的鄙视链
程序员的鄙视链
程序员必看的十大电影
程序员必看的十大电影
Java程序员必看电影
Java程序员必看电影
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
中美印日四国程序员比较
中美印日四国程序员比较
老程序员的下场
老程序员的下场
我的丈夫是个程序员
我的丈夫是个程序员
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
那些争议最大的编程观点
那些争议最大的编程观点
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有