Android實(shí)現(xiàn)定制桌面的方法
本文實(shí)例講述了Android實(shí)現(xiàn)定制桌面的方法。分享給大家供大家參考。具體如下:
launcher也就是我們的Home,可以簡(jiǎn)單地把它理解為一個(gè)簡(jiǎn)化的linux GUI。作為一個(gè)GUI它首先必須完成它最本分的功能,就是它必須能提供對(duì)所有應(yīng)用程序(CATEGORY_LAUNCHER)的映射;不過(guò)作為一個(gè) GUI,它除了做好本分之外還必須是符合大眾審美的美女(wallpaper);另外還必須具有良好的交互性,沒(méi)有良好的交互性就像你對(duì)一位美女殷勤了半天,她卻直接對(duì)無(wú)視,那結(jié)果是比較糟糕的~~
所謂兵馬未動(dòng),糧草先行,在了解launcher的細(xì)節(jié)之前,我們首先需要完成對(duì)一些知識(shí)的掃盲。當(dāng)然這些知識(shí)我們都可以在SDK guide大叔那邊找到,俺可以很負(fù)責(zé)任地告訴大家,如果你把SDK guide大叔的三板斧都學(xué)會(huì)了,APK你基本就處于無(wú)敵狀態(tài)了,絕對(duì)護(hù)甲+10000,最起碼基礎(chǔ)知識(shí)是夠了,其他比的就是創(chuàng)意了:
1、必須比較完整地了解APK的4個(gè)部件,尤其是Activity,現(xiàn)在可以簡(jiǎn)單地理解Activity是一個(gè)應(yīng)用程序的窗口。
2、必須了解UI的那部分內(nèi)容,這部分內(nèi)容是比較多的,English一般的我看得是比較抑郁的,但如果你想設(shè)計(jì)一個(gè)符合自己審美要求的美女或者帥哥是必須得得了解的,不需要一下能完全理解,但至少出了問(wèn)題你知道去哪部分查~~
3、Resources那部分內(nèi)容可以當(dāng)百科全書(shū)查
4、intent那部分內(nèi)容也是需要了解比較詳細(xì)的,他是和應(yīng)用溝通的渠道,大家可以參考一下小斯大蝦寫的文檔。
5、manifest必須了解,security可以看看
6、Graphic部分的內(nèi)容是給需要更高品味的GUI設(shè)計(jì)提供的,雖然它可能主要用在游戲上面,但我覺(jué)得如果要作出夠酷的GUI肯定是需要2d,3d引擎的。
7、AppWidget可以作為了解,用的時(shí)候再翻閱
各位路過(guò)的大蝦們肯定被這么多的糧草給直接雷倒了,其實(shí)需要我們?cè)敿?xì)掌握的是1和2,其他的都可以當(dāng)作百科全書(shū),但是如果能仔細(xì)地看透了那是最好了。
好,萬(wàn)事俱備只欠東風(fēng)了,我們首先來(lái)看看這個(gè)Home是在啥時(shí)候由誰(shuí)來(lái)啟動(dòng)的。這部分知識(shí)可以跳過(guò),但是理解一下是好的,你可以了解一個(gè)APK進(jìn)程是如何懷胎十月之后誕生的??赡芟旅嬲f(shuō)到的詞匯有些生澀,所以建議先看看Android Anatomy and Physiology.pdf。
Linux kernel啟動(dòng)以后會(huì)通過(guò)App_main進(jìn)程來(lái)初始化android Runtime Java運(yùn)行環(huán)境,而zygote是android的第一個(gè)進(jìn)程。所有的android的應(yīng)用以及大部分系統(tǒng)服務(wù)都是通過(guò)zygote fork出來(lái)的子進(jìn)程(我現(xiàn)在看到的只有native的service manager不是由zygote fork出來(lái)的)。在system server中啟動(dòng)的若干系統(tǒng)服務(wù)中與我們啟動(dòng)進(jìn)程相關(guān)的就是Acitivity Manager。
當(dāng)systerm server啟動(dòng)好所有服務(wù)以后,系統(tǒng)就進(jìn)入”system ready”狀態(tài),這個(gè)時(shí)候Activity Manager就登場(chǎng)了。Activity Manager光看代碼行就知道是一個(gè)重量級(jí)的服務(wù),它主要管理Activity之間的跳轉(zhuǎn),以及進(jìn)程的生命周期。當(dāng)Activity Manager發(fā)現(xiàn)系統(tǒng)已經(jīng)啟動(dòng)好以后它就會(huì)發(fā)出一個(gè)intent:
Intent intent = new Intent(
mTopAction,
mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
通過(guò)這個(gè)category類型為home的intent,Activity Manager就會(huì)通過(guò):
啟動(dòng)Home進(jìn)程了。而這個(gè)啟動(dòng)Home進(jìn)程的過(guò)程實(shí)際上還是去通過(guò)zygote fork出的一個(gè)子進(jìn)程。因此只要在manifest中具備這樣的intent-filter都可以在開(kāi)機(jī)的時(shí)候作為Home啟動(dòng):
<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>
多個(gè)home之間的switch會(huì)在開(kāi)始的時(shí)候有個(gè)選擇,至于這個(gè)選擇好像是package manager來(lái)實(shí)現(xiàn)的,沒(méi)有仔細(xì)研究過(guò)。
好啦,了解了Lancher是如何執(zhí)行的,我們?cè)賮?lái)看看整個(gè)lancher內(nèi)部構(gòu)造。看看一個(gè)lancher如何構(gòu)造才算是個(gè)長(zhǎng)得對(duì)得起觀眾的娃:
1、取得系統(tǒng)中所有安裝好的應(yīng)用程序,并提供能運(yùn)行這些程序的映射(形象的理解就是一個(gè)一個(gè)應(yīng)用程序的小圖標(biāo))。這是Lancher的骨架,正所謂何謂lancher是吧~~如果它不能提供應(yīng)用程序的訪問(wèn),再好看也至多是一個(gè)華麗的花瓶而已,啥用米有。
2、更好一點(diǎn)我們就需要為這個(gè)設(shè)計(jì)良好的骨架提供一些畫(huà)皮以及一系列動(dòng)畫(huà)效果,就是我們的wallpaper以及一系列的圖像,animation,graphic之類的。如果完成這部分工作,基本上我們的Home就基本成型了。
3、要使得我們的GUI更具親和性更方便使用,我們還提供一些額外的功能,比如說(shuō)現(xiàn)在lancher實(shí)現(xiàn)的圖標(biāo)的拖動(dòng),快捷方式等等。這些都是仁者見(jiàn)仁智者見(jiàn)智的事情,取決你天馬行空的設(shè)計(jì)了。
總結(jié)起來(lái)一個(gè)lancher包含3個(gè)部分內(nèi)容:應(yīng)用程序信息采集,事件處理,動(dòng)畫(huà)。下面我們來(lái)講述一個(gè)自己的launcher的實(shí)現(xiàn)過(guò)程:
1、設(shè)計(jì)
從純用戶的角度來(lái)設(shè)計(jì)你的界面,你希望達(dá)到什么樣的效果,盡量寫得詳細(xì)。尤其是應(yīng)用程序信息以如何方式的出現(xiàn),以及對(duì)它的操作一般都是一個(gè)好設(shè)計(jì)的亮點(diǎn)。我們現(xiàn)在設(shè)計(jì)一個(gè)簡(jiǎn)單的,我們需要一個(gè)墻紙,然后在這個(gè)墻紙上面有一個(gè)條形的控件來(lái)顯示我們的應(yīng)用程序圖標(biāo)。選擇這些圖標(biāo)以后會(huì)在屏幕中間出現(xiàn)一張圖表示這個(gè)應(yīng)用程序的功能,然后單擊這個(gè)圖就會(huì)打開(kāi)這個(gè)應(yīng)用程序。
2、設(shè)計(jì)的總體實(shí)現(xiàn)
針對(duì)自己的設(shè)想來(lái)設(shè)計(jì)這個(gè)lancher的整體實(shí)現(xiàn),如果有無(wú)法實(shí)現(xiàn)的內(nèi)容就要及時(shí)修改設(shè)計(jì),或者換一種設(shè)計(jì)方案。我們這里使用一個(gè) FrameLayout來(lái)作為我們的Lancher的容器。然后分層,最下面一層用來(lái)放置可能需要的快捷方式以及我們的 wallpaper,然后在wallpaper層上放一個(gè)我們自己定義的component來(lái)顯示我們的應(yīng)用程序信息。個(gè)人覺(jué)得FrameLayout是比較適合作為lancher的layout的,它類似于photoshop的圖層這樣的控制,上面的圖層會(huì)覆蓋下面的圖層。
3、具體功能的具體實(shí)現(xiàn)
這里具體到代碼上就是設(shè)計(jì)各種java功能類了。對(duì)于wallpaper和圖標(biāo)的拖拽移動(dòng)這里簡(jiǎn)單提一下,更多的可以去看Android Lancher的實(shí)現(xiàn)。wallpaper一般是注冊(cè)一個(gè)broadcastreceiver來(lái)處理系統(tǒng)中所有的更改背景圖片的請(qǐng)求,而圖標(biāo)的脫拽移動(dòng)則涉及到Draglayer這個(gè)類。
我們來(lái)把重點(diǎn)放在如何取得Android已安裝的應(yīng)用程序信息上。這里就涉及到我們另外一個(gè)重要的service了,它就是package manager,它負(fù)責(zé)對(duì)安裝的包進(jìn)行管理。這里涉及到一些權(quán)限,我是直接照著android lancher的實(shí)現(xiàn)把它的權(quán)限拷貝過(guò)來(lái)的:
<uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.SET_WALLPAPER" /> <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" />
下面來(lái)看看具體的實(shí)現(xiàn),我們創(chuàng)建一個(gè)自己的控件,使用LinearLayout來(lái)裝載ImageSwitcher和Gallery兩個(gè)控件,用 Gallery來(lái)顯示獲得的應(yīng)用程序信息,用ImageSwitcher來(lái)顯示應(yīng)用程序的介紹,單擊ImageSwitcher就能打開(kāi)相應(yīng)的應(yīng)用程序。
public class MyLancherSwitcher extends LinearLayout implements ViewSwitcher.ViewFactory, AdapterView.OnItemSelectedListener,AdapterView.OnItemClickListener{
…………
mImageSwitcher = new ImageSwitcher(context) ;
mGallery = new Gallery(context) ;
this.addView(mImageSwitcher, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,400)) ;
this.addView(mGallery, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 80)) ;
…………
}
架構(gòu)選好了,下面就是如何為這個(gè)兩個(gè)控件提供已安裝的應(yīng)用程序的信息,首先我們?nèi)〉胮ackage manager :
然后package manager通過(guò)intent信息來(lái)提供相應(yīng)的應(yīng)用程序信息:
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0); Collections.sort(apps, new ResolveInfo.DisplayNameComparator(manager));
然后我們定義個(gè)自己的類MyAppInfo來(lái)存儲(chǔ)這些取得的信息:
for (int i = 0; i < count; i++) {
MyAppInfo application = new MyAppInfo();
ResolveInfo info = apps.get(i);
application.title = info.loadLabel(manager);
application.setActivity(new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name),
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
application.icon = info.activityInfo.loadIcon(manager);
mApplications.add(application);
}
final void setActivity(ComponentName className, int launchFlags) {
intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(className);
intent.setFlags(launchFlags);
}
我們使用一個(gè)數(shù)組來(lái)存儲(chǔ)這些MyAppInfo信息,并把它提供給Gallery:
private static ArrayList<MyAppInfo> mApplications; mGallery.setAdapter(new ApplicationsAdapter(this.getContext(), mApplications)) ;
最后重載ArrayAdapter<MyAppInfo>的getView()函數(shù)對(duì)畫(huà)圖進(jìn)行一些裁減就OK了,Gallery就能顯示我們的應(yīng)用程序的圖片信息了。最后我們把Gallery中被選中的圖片的應(yīng)用程序信息傳給ImageSwitcher,并為ImageSwithcher注冊(cè)一個(gè)按鍵事件,就可以啟動(dòng)應(yīng)用程序了:
private OnClickListener mImageSwitcherListener = new OnClickListener(){
public void onClick(View v){
if(mAppInfo == null){}
else
v.getContext().startActivity(mAppInfo.intent);
}
};
這樣基本我們lancher的骨架就搞定了,不過(guò)還有一個(gè),那就是當(dāng)我們新安裝或刪除一個(gè)應(yīng)用程序的時(shí)候,我們的Home必須捕獲這個(gè)intent,并及時(shí)調(diào)整home里面的應(yīng)用程序信息,因此我要為我們的控件注冊(cè)一個(gè)package的broadcast receiver :
private class ApplicationsIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
loadApplications(false);
}
}
private void registerIntentReceivers() {
filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
registerReceiver(mApplicationsReceiver, filter);
}
Ok這樣我們的lancher就基本完成了,剩下的就是為各個(gè)事件添加你需要的動(dòng)畫(huà)效果,這里就不說(shuō)了。以前沒(méi)有經(jīng)歷過(guò)java編程,但是個(gè)人覺(jué)得 android java應(yīng)用的編程還是相對(duì)簡(jiǎn)單的,只是因?yàn)闁|西很多所以顯得有點(diǎn)復(fù)雜,但是基本上使用起來(lái)還是很方便的,基本就是繼承之后重載或者實(shí)現(xiàn)接口,而且 Android為Ui的編程提供了一個(gè)更方便的方式就是使用XML,使用xml可以更直觀地來(lái)進(jìn)行你的設(shè)計(jì),而且也方便了你以后的修改和移植
希望本文所述對(duì)大家的Android程序設(shè)計(jì)有所幫助。
- Android ListView的Item點(diǎn)擊效果的定制
- Android快速開(kāi)發(fā)之定制BaseTemplate
- Android實(shí)現(xiàn)定制返回按鈕動(dòng)畫(huà)效果的方法
- Android定制自己的EditText輕松改變底線顏色
- Android 組件樣式定制方法詳解
- android源碼探索之定制android關(guān)機(jī)界面的方法
- Android實(shí)現(xiàn)的狀態(tài)欄定制和修改方法
- Android 如何定制vibrator的各種震動(dòng)模式M 具體方法
- Android定制RadioButton樣式三種實(shí)現(xiàn)方法
- 詳解android系統(tǒng)的定制
相關(guān)文章
Android項(xiàng)目實(shí)現(xiàn)短信的發(fā)送、接收和對(duì)短信進(jìn)行攔截
本篇文章主要介紹了Android項(xiàng)目實(shí)現(xiàn)短信的發(fā)送、接收和對(duì)短信進(jìn)行攔截,這是學(xué)習(xí)Android比較入門的東西,有需要的可以了解一下。2016-10-10
Android將項(xiàng)目導(dǎo)出為L(zhǎng)ibrary并在項(xiàng)目中使用教程
這篇文章主要介紹了Android將項(xiàng)目導(dǎo)出為L(zhǎng)ibrary并在項(xiàng)目中使用教程,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07
Android自定義TextView仿微信朋友圈文字展開(kāi)全文功能
這篇文章主要為大家詳細(xì)介紹了Android自定義TextView仿微信朋友圈文字展開(kāi)全文功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
Android利用Flutter?path繪制粽子的示例代碼
端午將至,作為中華民族的非常重要的傳統(tǒng)節(jié)日,粽子那是必不可少的。今天跟隨本篇文章用Flutter?path畫(huà)一個(gè)會(huì)科普節(jié)日的的粽子吧2022-05-05
關(guān)于Android Studio封裝SDK的那些事兒
這篇文章主要給大家介紹了關(guān)于Android Studio封裝SDK的那些事兒,文中通過(guò)圖文以及示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09
Android實(shí)現(xiàn)隱私政策彈窗與鏈接功能
現(xiàn)在幾乎所有的應(yīng)用市場(chǎng)都要求應(yīng)用上架需要用戶協(xié)議/隱私政策,本篇內(nèi)容將介紹如何在APP內(nèi)植入一個(gè)隱私政策彈窗與鏈接,對(duì)Android隱私政策彈窗實(shí)現(xiàn)代碼感興趣的朋友跟隨小編一起看看吧2021-07-07
Android中用MediaRecorder進(jìn)行錄影的實(shí)例代碼
這篇文章主要介紹了Android中用MediaRecorder進(jìn)行錄影的實(shí)例代碼,有需要的朋友可以參考一下2014-01-01
Android實(shí)現(xiàn)獲取應(yīng)用程序相關(guān)信息列表的方法
這篇文章主要介紹了Android實(shí)現(xiàn)獲取應(yīng)用程序相關(guān)信息列表的方法,是應(yīng)用管理器常用的功能,需要的朋友可以參考下2014-07-07

