言归正传,要想自己写个一模一样的Launcher来,我们就得先对着模拟器或者Android系统的机子,好好对每次第一个启动起来的这个看似简单却深藏不露的启动器。通过一番折腾,大致可以将Launcher实现的功能分为如下几个:
1、在空的位置长按,具备添加应用、快捷方式、文件夹和小部件的功能
2、左右可以滑动的屏幕
3、可以更换壁纸
4、长按桌面上面某个item(上面说的四个可以添加到桌面的东东),就可以任意拖动了,同时下面的SldingDrawer位置会变成一个垃圾箱,你将拖拽的item放到垃圾箱的位置其颜色变红的时候,就意味着你一放手,该item就被删除了
5、桌面下方是个SlidingDrawer,你一点就弹上来,在里面就是所有的应用,长按可以将其拖到桌面。
有了这样几个功能分类,我们的任务也就非常明了了。我们就来分析并思考怎么样才能实现每个功能,最后融合为你现在所看到的效果。
我们首先看第一个问题。
简单的思考了下,觉得应该很简单,就是监听下界面的长按事件,在该事件中,弹出一个应用列表就OK了,如果这个弹出的应用列表还可以调用系统自带的,那就更省事了。
第二个问题:
滑动的屏幕,一开始还不知道怎么实现,晚上下班的时候,一个人闷闷不乐地上了公交车,站到了窗口的位置,一双黯然的眼神充满了犹豫,可是脑子里始终是这个问题。当公交车开动的时候,当窗外的一切在我的眼前缓缓向后退去的时候,我如梦初醒,失声惊叫,原来如此!幸好声音不大,否则又要出丑一次。原来手机屏幕就相当于公交车的窗口,背后是一个大风景,只不过当我们拿着手机的时候,这个窗口是静止的,但是当我们滑动的时候,风景是随着移动的。至于,这个是怎么移动的等细节问题,后面再去慢慢分析。
第三个问题:
关于更换壁纸,由于之前做过一个,所以,不用想太多,直接调用调用系统壁纸选择应用,再实现一个BroadcastReciever,监听下壁纸的改变,获得一个Bitmap类型就行了。
但是这里关键是获得Bitmap后如何将其显示出来,并随着屏幕的滑动,壁纸也要相应地移动,这里壁纸就相当于上面讲的风景,目前想到的是直接将其设置为背景,但是觉得在多个屏幕之间,不可行。
第四个问题:
拖动本身并不难,但是要在多个屏幕之间拖动就比较难办了。这个没有具体的思路,只能在实现第二个问题后,再融合多屏幕和拖拽的功能了。
第五个问题:
这个很简单,SlidingDrawer的content为一个GridView,GridView的每个item就是一个应用,关键是长按某个item就将其拖动到桌面,这个暂时也么有思路,待后面走到这一步再思考吧。
到此,要实现的功能已经各个功能大致的思路就有了。但是,当要下手时,又发现光有这些还是毫无头绪,没办法,还是要先来打第一仗,做到了解“敌人”的目的。所以,对Launcher的源码大致看了下,主要看其每个类的用途,找准其设计思想。这里不用纠结于某个类的某个具体的方法的具体功能,只需要知道每个类是干什么的就可以了,然后分个主次关系,看看哪些是关键,哪些是次要的,哪些是附属品...
经过第一战役,获得如下成果:
一、桌面的每种类型的item进行了类的封装,主要层次关系如下图:
——ItemInfo
——ApplicationInfo
——FolderInfo
——LiveFolderInfo
——UserFolderInfo
——Widget
二、整个布局层次如下图:
——DragLayer
——Workspace
——CellLayout
——CellInfo(Application,Shortcut,Folder,Widget)
——CellLayout
——CellLayout
-----------------------------------------
三、关键的几个重要的类:CellLayout,Workspace,Launcher,DragLayer,把握这几个基本就清楚了桌面的布局。其中最外层是DragLayer,控制桌面上item的拖动,DragLayer中是一个Workspace,Workspace就是整个桌面,由几个CellLayout横铺组成,主要控制多屏幕的滑动,壁纸的绘制;CellLayout是一个自定义布局控件,其功能类似一个GridView,由m*n个单元格(Cell)组成,其主要负责桌面长按事件的处理,获得长按的区域信息,主要需要判断当前区域是空的还是已经被占用了,同时,控制item的拖动。CellLayout中放的就是上面几种类型的item了。item的拖动功能,是由DragLayer,Workspace,CellLayout协同完成的。
好了,至此,基本应用可以动手了。先不关注其他类的具体用途,先搞定所有的布局!