日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android_launcher的源码详细分析

發(fā)布時間:2024/8/24 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android_launcher的源码详细分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載請注明出處:http://blog.csdn.net/fzh0803/archive/2011/03/26/6279995.aspx

去年做了launcher相關(guān)的工作,看了很長時間。很多人都在修改launcher,但還沒有詳細(xì)的文檔,把自己積累的東西分享出來,大家一起積累。這份源碼是基于2.1的launcher2,以后版本雖有變化,但大概的原理一直還是保留了。

一、主要文件和類

1.Launcher.java:launcher中主要的activity。

2.DragLayer.java:launcher layout的rootview。DragLayer實(shí)際上也是一個抽象的界面,用來處理拖動和對事件進(jìn)行初步處理然后按情況分發(fā)下去,角色是一個controller。它首先用onInterceptTouchEvent(MotionEvent)來攔截所有的touch事件,如果是長按item拖動的話不把事件傳下去,直接交由onTouchEvent()處理,這樣就可以實(shí)現(xiàn)item的移動了,如果不是拖動item的話就把事件傳到目標(biāo)view,交有目標(biāo)view的事件處理函數(shù)做相應(yīng)處理。如過有要對事件的特殊需求的話可以修改onInterceptTouchEvent(MotionEvent)來實(shí)現(xiàn)所需要的功能。

3. DragController.java:為Drag定義的一個接口。包含一個接口,兩個方法和兩個靜態(tài)常量。接口為DragListener(包含onDragStart(),onDragEnd()兩個函數(shù)),onDragStart()是在剛開始拖動的時候被調(diào)用,onDragEnd()是在拖動完成時被調(diào)用。在launcher中典型的應(yīng)用是DeleteZone,在長按拖動item時調(diào)用onDragStart()顯示,在拖動結(jié)束的時候onDragEnd()隱藏。兩個函數(shù)包括startDrag()和setDragItemInfo().startDrag()用于在拖動是傳遞要拖動的item的信息以及拖動的方式,setDragItemInfo()用于傳遞item的參數(shù)信息(包括位置以及大小)。兩個常量為DRAG_ACTION_MOVE,DRAG_ACTION_COPY來標(biāo)識拖動的方式,DRAG_ACTION_MOVE為移動,表示在拖動的時候需要刪除原來的item,DRAG_ACTION_COPY為復(fù)制型的拖動,表示保留被拖動的item。

4.LauncherModel.java:輔助的文件。里面有許多封裝的對數(shù)據(jù)庫的操作。包含幾個線程,其中最主要的是ApplicationsLoader和DesktopItemsLoader。ApplicationsLoader在加載所有應(yīng)用程序時使用,DesktopItemsLoader在加載workspace的時候使用。其他的函數(shù)就是對數(shù)據(jù)庫的封裝,比如在刪除,替換,添加程序的時候做更新數(shù)據(jù)庫和UI的工作。

5.Workspace.java:抽象的桌面。由N個celllaout組成,從cellLayout更高一級的層面上對事件的處理。

6.LauncherProvider.java:launcher的數(shù)據(jù)庫,里面存儲了桌面的item的信息。在創(chuàng)建數(shù)據(jù)庫的時候會loadFavorites(db)方法,loadFavorites()會解析xml目錄下的default_workspace.xml文件,把其中的內(nèi)容讀出來寫到數(shù)據(jù)庫中,這樣就做到了桌面的預(yù)制。

7.CellLayout.java:組成workspace的view,繼承自viewgroup,既是一個dragSource,又是一個dropTarget,可以將它里面的item拖出去,也可以容納拖動過來的item。在workspace_screen里面定了一些它的view參數(shù)。

8.ItemInfo.java:對item的抽象,所有類型item的父類,item包含的屬性有id(標(biāo)識item的id),cellX(在橫向位置上的位置,從0開始),cellY(在縱向位置上的位置,從0開始)?,spanX(在橫向位置上所占的單位格),spanY(在縱向位置上所占的單位格),screen(在workspace的第幾屏,從0開始),itemType(item的類型,有widget,search,application等),container(item所在的)。

9.UserFolder.java:?用戶創(chuàng)建的文件夾。可以將item拖進(jìn)文件夾,單擊時打開文件夾,長按文件夾上面標(biāo)題處可以重命名文件夾。

10.LiveFolder.java:系統(tǒng)自帶的文件夾。從系統(tǒng)中創(chuàng)建出的如聯(lián)系人的文件夾等。

11.DeleteZone:刪除框。在平時是出于隱藏狀態(tài),在將item長按拖動的時候會顯示出來,如果將item拖動到刪除框位置時會刪除item。DeleteZone實(shí)現(xiàn)了DropTarget和DragListener兩個接口。

12.LauncherSettings.java:字符串的定義。數(shù)據(jù)庫項(xiàng)的字符串定義,另外在這里定義了container的類型,還有itemType的定義,除此還有一些特殊的widget(如search,clock的定義等)的類型定義。

?

二、主要模塊

1.界面模型:

?

?
??

?

?

?

Launcher的界面的rootview是DragLayer,它是一個FrameLayout,在它上面workspace(應(yīng)該說是celllayout)占了絕大部分的空間,celllayout的參數(shù)文件是workspace_screen.xml。workspace既是一個DropTarget又是一個DragSource,可以從AllAppGridView中拖出應(yīng)用程序放在它上面,也可以把它里面的item拖走刪除或者拖到bottomabr里面去。

2.Drop& Drag模型:

?????????DragSource:可以拖動的對象來源的容器,在launcher中主要有AllAppGridView,workspace等。

???????????????????void onDropCompleted(View target, boolean success,int x,int y);

DropTarget:可以放置被拖動的對象的容器。在launcher中有folder,workspace,bottombar等,一個View既可以是Dragsource也可以是DropTarget。主要包含以下幾個接口:

boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);

acceptDrop函數(shù)用來判斷dropTarget是否可以接受item放置在自己里面。

???void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);

??????????onDragEnter是item被拖動進(jìn)入到一個dropTarget的時候的回調(diào)。

???void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);

??????????onDragOver是item在上一次位置和這一次位置所處的dropTarget相同的時候的回調(diào)。

???void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);

??????????onDragExit是item被拖出dropTarget時的回調(diào)。

boolean onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);

?????onDrop是item被放置到dropTarget時的回調(diào)。?

函數(shù)的調(diào)用模式為:

DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);

if?(dropTarget !=?null) {

??????????????/**

???????????????*?當(dāng)這一次的?target?跟上一次相同時,根據(jù)坐標(biāo)來移動item

???????????????*/

????????????????if?(mLastDropTarget?== dropTarget) {

????????????????????dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1],

????????????????????????(int)?mTouchOffsetX, (int)?mTouchOffsetY,?mDragInfo);

????????????????}?else?{

??????????????????/**

?????????????????*?當(dāng)上一次的位置跟這一次不同而且上一次的位置不為空,說明item移???????????*動出了,將上次的?View?根據(jù)上次的坐標(biāo)重新排列,并根據(jù)當(dāng)前坐標(biāo)重排*當(dāng)前的*/

????????????????????if?(mLastDropTarget?!=?null) {

????????????????????????mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],

????????????????????????????????(int)?mTouchOffsetX, (int)?mTouchOffsetY,?mDragInfo);

????????????????????}

????????????????????dropTarget.onDragEnter(mDragSource, coordinates[0], coordinates[1],

????????????????????????(int)?mTouchOffsetX, (int)?mTouchOffsetY,?mDragInfo);

??????????????????

????????????????}

????????????}?else?{//如果這一次為?null ,上一次不為?null ,那么把上一次坐標(biāo)位置的?cell?去掉

????????????????if?(mLastDropTarget?!=?null) {

????????????????????mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],

????????????????????????????(int)?mTouchOffsetX, (int)?mTouchOffsetY,?mDragInfo);

???????????????????

????????????????}

????????????}

????????????//記錄上次的droptarget

????????????mLastDropTarget?= dropTarget;

3.Touch event總結(jié):

???????????????????由于launcher的事件比較多比較復(fù)雜,所以在事件處理的時候一般采用rootview先用onInterceptTouchEvent(MotionEvent)攔截所有的touch事件,經(jīng)過判斷后分發(fā)給childview。

判斷的規(guī)則如下:

????????a.down事件首先會傳遞到onInterceptTouchEvent()方法

???????b.如果該ViewGroup的onInterceptTouchEvent()在接收到down事件處理完成之后return false,那么后續(xù)的move, up等事件將繼續(xù)會先傳遞給該ViewGroup,之后才和down事件一樣傳遞給最終的目標(biāo)view的onTouchEvent()處理。

???????c.如果該ViewGroup的onInterceptTouchEvent()在接收到down事件處理完成之后return true,那么后續(xù)的move, up等事件將不再傳遞給onInterceptTouchEvent(),而是和down事件一樣傳遞給該ViewGroup的onTouchEvent()處理,注意,目標(biāo)view將接收不到任何事件。

???????d.如果最終需要處理事件的view的onTouchEvent()返回了false,那么該事件將被傳遞至其上一層次的view的onTouchEvent()處理。

???????e.如果最終需要處理事件的view?的onTouchEvent()返回了true,那么后續(xù)事件將可以繼續(xù)傳遞給該view的onTouchEvent()處理。

?

?

三、幾種問題的解決方式

1.將所有的應(yīng)用都排列在桌面上

?????????將所有的應(yīng)用都排列在桌面是通過首先創(chuàng)建一個三維的boolean型全局?jǐn)?shù)組來記錄item的排列情況,第一維是屏數(shù),第二維是縱向上的排列情況,第三維是橫向的排列情況,如果那個位置被item所占用就標(biāo)記為1,否則標(biāo)記為0.在啟動時把全局?jǐn)?shù)組初始化為0,然后在添加的時候把相應(yīng)的位置置1.凡是涉及到workspace上item的變化,比如移動、添加、刪除操作時都需要維護(hù)數(shù)組,保持?jǐn)?shù)組的正確性,因?yàn)樵诎惭b新程序時依據(jù)數(shù)組的狀態(tài)去判斷把item加到什么位置。

2.動態(tài)增加屏幕

動態(tài)增加屏幕是通過worksapce .addchild(view)的方式實(shí)現(xiàn)。基本思路是:首先預(yù)先規(guī)定所允許的最大的屏幕數(shù),然后在需要增加屏幕而且當(dāng)前屏幕數(shù)沒有超過最大屏幕數(shù)的時候通過(CellLayout)mInflater.inflate(R.layout.workspace_screen,null)創(chuàng)建一個celllayout實(shí)例出來,然后通過addchild把它加入進(jìn)去。在屏幕上的item被刪除時通過從最后一屏起判斷屏幕上是否有item,如果有的話保留,沒有的話則刪除最后一屏,以此類推。

3.預(yù)制桌面

?????????a.添加普通的應(yīng)用程序快捷方式:

?????????在../res/xml下的default_workspace.xml文件中加入默認(rèn)要放置的普通的應(yīng)用程序。加入的格式為:

<favorite

launcher:packageName="... "????//應(yīng)用的packageName??

launcher:className="... "??????//應(yīng)用啟動時的第一個activity?

launcher:screen="..."?????????//放置在第幾屏(放在workspace的時候需要,從0開始,0為第一屏,1為第二屏,以此類推...)

launcher:x="..."???????????????//放置x方向的位置(在列中的位置)

launcher:y="..." />???????????//放置y方向的位置(在行中的位置)

packageName和className可以通過點(diǎn)擊程序,然后在打印出的log中找到comp={...},例如如下信息:

comp={com.estrongs.android.taskmanager/com.estrongs.android.taskmanager.TaskManager}。其中com.estrongs.android.taskmanager為packageName, com.estrongs.android.taskmanager.TaskManager為className。

workspace的布局如下:

(0,0)

(1,0)

(2,0)

(3,0)

(4,0)

(0,1)

(1,1)

(2,1)

(3,1)

(4,1)

(0,2)

(1,2)

(2,2)

(3,2)

(4,2)

?????????b.添加widget:

?????????在../package/apps/VLauncher/res/xml下的default_workspace.xml文件中加入默認(rèn)要放置的普通的應(yīng)用程序。加入的格式為:

<widget

launcher:packageName="..."???????//widget的packageName

launcher:className=" ..."???????//實(shí)現(xiàn)?widget的?receiver?類的名稱.

????launcher:container="..."????????//放置的位置(只能為desktop)

????????launcher:screen="..."????????//放置在第幾屏上

????????launcher:x="..."??????????????//放置的x位置

????????launcher:y="..."??????????????//放置的y位置

????????launcher:spanx="..."?????????//在x方向上所占格數(shù)

????????launcher:spany="..."/>???????//在y方向上所占格數(shù)

?

例如,要在第3屏的第一行第二列放置開始放置一個x方向上占兩個單位格,y方向上占兩個單位格的時鐘,可以加入以下代碼:

<appwidget

launcher:packageName="com.android.alarmclock"??????launcher:className="com.android.alarmclock.AnalogAppWidgetProvider"

????????launcher:container="desktop"

????????launcher:screen="2"

????????launcher:x="1"

????????launcher:y="0"

????????launcher:spanx="2"

????????launcher:spany="2"/>?

4.改變主界面的排列方式

?????????要修改桌面的排列方式,如下,先根據(jù)橫豎屏設(shè)置修改workspace_screen.xml里shortAxisCells和longAxisCells的參數(shù),然后在Launcher.java中修改NUMBER_CELLS_X和NUMBER_CELLS_Y的值,在2.3版本中剛開始往數(shù)據(jù)庫中添加item的時候會去判斷,如果不修改NUMBER_CELLS_X和NUMBER_CELLS_Y的話會導(dǎo)致一部分的item顯示不出來,導(dǎo)致預(yù)制apk的失敗。

5.增加worksapce上的屏數(shù)

?????????要增加屏數(shù),首先在根據(jù)橫豎屏在launcher.xml中的<com.android.launcher.Workspace?中刪除或增加?<include android:id="@+id/cellN" layout="@layout/workspace_screen" />,然后在Launcher.java中修改SCREEN_COUNT的值即可。

?

四、xml文件

???????1.workspace_screen.xml

??????????????launcher:cellWidth="95dip"

???????????cell(即item)的寬

????????launcher:cellHeight="93dip"

???????????cell(即item)的寬

????????launcher:longAxisStartPadding="25dip"

較長(屏幕的寬和高中較大的那一方向,根據(jù)橫豎屏方向有所不同)方向上距離起點(diǎn)的像素?cái)?shù)

????????launcher:longAxisEndPadding="55dip"

較長(屏幕的寬和高中較大的那一方向,根據(jù)橫豎屏方向有所不同)方向上距離終點(diǎn)的像素?cái)?shù)

????????launcher:shortAxisStartPadding="20dip"

較短(屏幕的寬和高中較大的那一方向,根據(jù)橫豎屏方向有所不同)方向上距離起點(diǎn)的像素?cái)?shù)

????????launcher:shortAxisEndPadding="120dip"

較短(屏幕的寬和高中較大的那一方向,根據(jù)橫豎屏方向有所不同)方向上距離起點(diǎn)的像素?cái)?shù)

????????launcher:shortAxisCells="3"

較短的方向上可以容納的cell的數(shù)量

????????launcher:longAxisCells="5"

較長的方向上可以容納的cell的數(shù)量

shortAxisCells和longAxisCells決定一個workspace(即CellLayout)上可以容納的item的個數(shù)為shortAxisCells*longAxisCells.

2. application_boxed.xml

???????所有應(yīng)用程序和系統(tǒng)文件夾中item的定義。

3.application.xml

???????Workspace的item的layout定義。

轉(zhuǎn)載于:https://www.cnblogs.com/MMLoveMeMM/articles/4204941.html

總結(jié)

以上是生活随笔為你收集整理的android_launcher的源码详细分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品嫩草久久久久 | 在线看欧美 | 一级黄色免费观看 | 亚洲成人www | 69式视频 | 青青草青青操 | 亚洲字幕成人中文在线观看 | 国产一区不卡在线 | 欧美精品亚洲一区 | 色伊人| 日韩欧美一区二区三区在线观看 | 国产aⅴ激情无码久久久无码 | 中文字幕网伦射乱中文 | 欧美精品aa | 精品国产制服丝袜高跟 | 国外亚洲成av人片在线观看 | 国内福利视频 | 性感少妇av | 色哟哟一区二区 | 午夜草逼 | 欧美日韩大片 | 四虎一区二区 | 毛片在线播放视频 | 在线观看免费人成视频 | www.日韩在线 | 久热精品视频 | 亚洲美女操 | 欧美日韩一区二区三区在线播放 | 黄色片欧美 | 日韩三级国产精品 | 日本一区二区免费在线 | 超碰97在线资源站 | 欧美成人三区 | 韩日视频在线观看 | 欧洲精品视频在线 | 91色视频在线 | 啪啪福利社 | 狠狠久久 | 精品视频在线观看免费 | 欧美一区二区三区粗大 | 日韩精品在线观看视频 | 91精品国产一区二区三竹菊影视 | 天天干天天爽天天操 | 狠狠干干 | 国产精品污污 | 久久99国产精品久久99果冻传媒 | 精品久久久中文字幕人妻 | 特黄aaaaaaaaa真人毛片 | 精品欧美一区二区久久久 | 美国av毛片 | 国产精品国产三级国产专播精品人 | 男同互操gay射视频在线看 | 欧美一区二区三区久久精品 | 夜色资源网 | а√天堂8资源中文在线 | 亚洲精品国产a | 国产91一区 | 亚洲做受高潮无遮挡 | 国产在线观看免费网站 | 国产福利免费在线观看 | 成人精品在线 | 爽爽爽av| 欧美日韩在线观看一区二区三区 | 国产成人精品视频在线 | 天天干天天噜 | 日韩在线观看免费全 | 浓精h攵女乱爱av | 日韩精品在线免费观看视频 | 91国偷自产一区二区三区观看 | 天天操狠狠干 | 久操久操久操 | 四虎啪啪 | 国产精品无码乱伦 | 少妇三级全黄 | 99爱在线观看 | 欧美精品 在线观看 | 免费无码毛片一区二区app | 欧美日韩a级片 | 亚洲男人皇宫 | 亚洲专区第一页 | 波多野结衣一区二区三区四区 | 91久久久久| 激情伦成人综合小说 | 久草精品视频 | 大咪咪dvd | 国产一级二级三级视频 | 国产xxxx孕妇 | 成人毛片100部免费看 | 中文字幕在线观看视频一区 | 体感预报日剧 | 国产精品精品久久久久久 | 麻豆视频免费入口 | 人人插人人看 | 综合亚洲视频 | 亚洲国产欧美在线观看 | 国产又爽又黄的激情精品视频 | xxxx亚洲 | 日韩天堂av | 国产欧美一区二区三区在线看 |