一.主要文件和类
1.Launcher.java:launcher中主要的activity。系统第一个启动的应用程序,在AndroidManifest.xml中定义了<category android:name="android.intent.category.HOME" />
2.LauncherApplication.java:应用程序全局初始化类,创建全局使用的应用程序缓存器Iconcache,创建全局使用的数据库加载类LauncherModel,注册事件监听器,注册数据库变化监听器
(在AndroidManifest.xml定义的Application)
3.IconCache.java:应用程序缓存器,通过一个HashMap<ComponentName,CacheEntry> mcache来缓存应用程序信息。内部类CachEntry对应存储应用程序的基本信息。makeDefaultIcon来创建默认的应用程序图标
4.LauncherModel.java:模型文件,封装了对数据库的操作。包含几个线程,加载所有应用程序和workspace的时候使用(loadAndBindAllApps,loadAndBindWorkspace)。其他的函数就是对数据库的封装,接口Callbacks提供加载程序和快捷方式的抽象方法。
5.LauncherProvider.java:launcher的数据库,里面存储了桌面的item的信息。在创建数据库的时候会调用loadFavorites(db)方法,解析xml目录下的default_workspace.xml文件,把其中的内容读出来写到数据库中,这样就得到了默认桌面的配置。
6.ItemInfo.java:对item的抽象,所有类型item的父类,item包含的属性有id(标识item的id),cellX(在横向位置上的位置,从0开始),cellY(在纵向位置上的位置,从0开始) ,spanX(在横向位置上所占的单位格),spanY(在纵向位置上所占的单位格),screen(在workspace的第几屏,从0开始),itemType(4种item类型,有widget,user_folder,application,shortcut),container(三种item存放的地方desktop,application,user_folder)。
7.Workspace.java:抽象的桌面。由N个cellLayout组成, 从cellLayout更高一级的层面上对事件的处理。Launcher.java中通过bindItems添加cellLayout.实现了DropTarget, DragSource, DragScroller。既是拖拽源,又是拖拽目的地,还可以左右拖动。
8.CellLayout.java:桌面的某一屏。是组成workspace的view,被划分成4X4的cell空间,用boolean[][]mOccupied来标识每个cell是否被占用.
9.AllApp2D.java:显示和存储应用程序列表的视图。。android自带的AllApp2D包括一个GridView和一个HomeButton,MTK修改成PagerControl,HorizontalPager和4个imageview。
10.HorizontalPager.java:AllApp2D中间的网格控件。由N个GridView组成,AllApps2D.java中通过addGridView添加GridView。
11.DeleteZone.java:删除框。在平时是出于隐藏状态,在将item长按拖动的时候会显示出来,如果将item拖动到删除框位置时会删除item。DeleteZone实现了DropTarget和DragListener两个接口。
12.DragLayer.java:launcher.xml的rootview。DragLayer实际上也是一个抽象的界面,用来处理拖动和对事件进行初步处理然后按情况分发下去,角色是一个DragController。它首先用onInterceptTouchEvent(MotionEvent)来拦截所有的touch事件,如果是长按item拖动的话不把事件传下去,直接交由onTouchEvent()处理,这样就可以实现item的移动了,如果不是拖动item的话就把事件传到目标view,交有目标view的事件处理函数做相应处理。
13. DragController.java:为拖拽定义的一个接口。包含一个接口,一个方法和两个静态常量。
接口为DragListener(包含onDragStart(),onDragEnd()两个函数),
onDragStart()是在刚开始拖动的时候被调用,
onDragEnd()是在拖动完成时被调用。
在launcher中典型的应用是DeleteZone,在长按拖动item时调用onDragStart()显示,在拖动结束的时候调用onDragEnd()隐藏。
一个函数包括用于在拖动是传递要拖动的item的信息以及拖动的方式
两个常量为DRAG_ACTION_MOVE,DRAG_ACTION_COPY来标识拖动的方式,DRAG_ACTION_MOVE为移动,表示在拖动的时候需要删除原来的item,
DRAG_ACTION_COPY为复制型的拖动,表示保留被拖动的item。
14.UserFolder.java: 用户创建的文件夹。实现了DropTarget,是拖拽目的地,可以将item拖进文件夹,单击时打开文件夹,暂不能处可以重命名文件夹。
15.LiveFolder.java:系统自带的文件夹。从系统中创建出的所有联系人的文件夹等。
16.AddAdapter.java:长按桌面弹出的”添加到主屏幕”对话框所对应的适配器。。
17.ShortcutAdapter.java:添加快捷方式的对话框所对应的适配器
18.LauncherSettings.java:数据库项的字符串定义,
19.Drop& Drag模型:
DragSource.java:可以拖动的对象来源的容器,在launcher中有AllApps2D,Folder,Workspace。
void onDropCompleted(View target, boolean success,int x,int y);
DropTarget.java:可以放置被拖动对象的容器。在launcher中有UserFolder,Workspace,DeleteZone,EXFolderIcon,一个View既可以是Dragsource也可以是DropTarget。
DropTarget.java主要包含以下几个抽象方法:
1) acceptDrop 函数用来判断dropTarget是否可以接受item放置在自己里面。
2) onDragEnter是item被拖动进入到另一个dropTarget的时候的回调。
3) onDragOver是item在上一次位置和这一次位置所处的dropTarget相同的时候的回调。
4) onDragExit是item被拖出dropTarget时的回调。
5) onDrop是item被放置到dropTarget时的回调。
例如DragController.java中onTouchEvent函数的MOVE动作:
if (dropTarget != null) {
if (mLastDropTarget == dropTarget) {
/* 当这一次的target 跟上一次相同时,onDragOver*/
dropTarget.onDragOver();
} else {
/* 当上一次的target 跟这一次不同时,onDragEnter*/
if (mLastDropTarget != null) {
/*当上一次的target不为空先执行onDragExit*/
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 {
/*当这一次的target为空,上一次target不为空 ,onDragExit*/
if (mLastDropTarget != null) {
mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
(int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
}
}
二.主要XML布局文件
launcher.xml和all_apps_button.xml
1.Launcher.xml分析
<com.mediatek.launcherplus.DragLayer android:id="@+id/drag_layer">
//主菜单界面,引用all_apps_2d.xml
<include layout="@layout/all_apps" />
<FrameLayout android:id="@+id/FrameLayout01">
//待机界面,WorkSpace包括7屏CellLayout
<com.mediatek.launcherplus.Workspace android:id="@+id/default_workspace"
launcher:defaultScreen="0">
<include android:id="@+id/cell1" layout="@layout/default_workspace_screen" />
<include android:id="@+id/cell2" layout="@layout/default_workspace_screen" />
<include android:id="@+id/cell3" layout="@layout/default_workspace_screen" />
<include android:id="@+id/cell4" layout="@layout/default_workspace_screen" />
<include android:id="@+id/cell5" layout="@layout/default_workspace_screen" />
<include android:id="@+id/cell6" layout="@layout/default_workspace_screen" />
<include android:id="@+id/cell7" layout="@layout/default_workspace_screen" />
</com.mediatek.launcherplus.Workspace>
</FrameLayout>
<RelativeLayoutandroid:id="@+id/bottom_layer"
android:layout_height="77dip" android:layout_gravity="bottom">
<RelativeLayout android:id="@+id/relative_layout_bar" android:layout_height="77dip" android:layout_gravity="bottom">
//底部的电话,联系人,信息,应用程序4个图标
<ImageView android:id="@+id/phone"android:src="@drawable/ic_launcher_phone"/>
<ImageView android:id="@+id/contact" android:src="@drawable/phonebook"/>
<ImageView android:id="@+id/message" android:src="@drawable/ic_messaging"/>
<com.mediatek.launcherplus.HandleView
android:id="@+id/all_apps_button" android:src="@drawable/home_menu"/>
<ImageView android:id="@+id/switch_shortcut_widget"
//底部的电话,联系人,信息,应用程序4个字符串
<TextView android:id="@+id/phone_text" android:text="@string/phone"/>
<TextView android:id="@+id/contact_text" android:text="@string/contact"/>
<TextView android:id="@+id/message_text" android:text="@string/message"/>
<TextView android:id="@+id/apps_text" android:text="@string/apps"/>
</RelativeLayout>
//底部的删除图标
<com.mediatek.launcherplus.DeleteZone android:id="@+id/delete_zone" android:src="@drawable/delete_zone_selector"/>
</RelativeLayout>
//中间的页面指示器
<com.mediatek.launcherplus.PagerControl android:id="@+id/workspace_control"/>
</com.mediatek.launcherplus.DragLayer>
2.all_apps_button.xml分析
<com.mediatek.launcherplus.AllApps2D android:id="@+id/all_apps_view"
android:background="@drawable/all_apps_background">
//顶部的页面指示器
<com.mediatek.launcherplus.PagerControl android:id="@+id/control"/>
//中间的可以左右滑动的Horizontal页面
<com.mediatek.launcherplus.HorizontalPager android:id="@+id/pager"
android:layout_height="340dip" launcher:pageWidth="320dip"/>
<RelativeLayout android:id="@+id/all_bottom_layer"
android:layout_height="77dip" android:layout_gravity="bottom">
<RelativeLayout android:id="@+id/all_relative_layout_bar">
//底部的电话,联系人,信息,主页图标
<ImageView android:id="@+id/all_phone" android:src="@drawable/ic_launcher_phone"/>
<ImageView android:id="@+id/all_contact" android:src="@drawable/phonebook"/>
<ImageView android:id="@all_all_apps_button" android:src="@drawable/menu_home"/>
<ImageView android:id="@+id/all_message" android:src="@drawable/ic_messaging"/>
//底部的电话,联系人,信息,主页字符串
<TextView android:id="@+id/phone_text" android:text="@string/phone"/>
<TextView android:id="@+id/contact_text" android:text="@string/contact"/>
<TextView android:id="@+id/message_text" android:text="@string/message"/>
<TextView android:id="@+id/apps_text" android:text="@string/home"/>
</RelativeLayout>
</RelativeLayout>
//中间的正在加载,请稍等
<TextView android:id="@+id/loading" android:text="@string/all_app_loading"/>
</com.mediatek.launcherplus.AllApps2D>