http://blog.csdn.net/lixuyuan/article/details/6688859
一、Launcher功能介绍
Launcher简称HomeScreen,是android手机加载完毕后第一个启动的应用程序,它负责除应用本身操作外的所有操作,包括有几个桌面、点击应用程序图标启动应用程序、长时间按桌面出现上下文菜单、长按桌面图标出现垃圾箱、长按桌面应用程序后可以移动位置和设置壁纸等,虽然它负责的操作看是很多,但它和普通的应用程序具有一样的权限。
二、Launcer 中一些重要的类及其功能描述
为了成为系统启动后第一个启动的应用程序,Launcher必须在其AndroidManifest.xml中添加<category android:name="android.intent.category.HOME" />属性。
AddAdapter .java: 长按桌面后弹出的添加到桌面对话框所对应的适配器。
AllApps2D.java: 用于存储和现实所有应用程序列表 的视图。
DeleteZone.java: 代表长按桌面应用程序所出现的删除按钮。
DragController.java: 用于控制拖动应用程序过程的类。
DragSource:.java 定义一个可以成为拖动对象的接口。
DragTarget.java: 定义一个可以接受并处理拖动的接口。
InstallShortcutReceiver.java: 安装快捷方式的接听器。
Launcher.java: Launcher应用程序从Launcher开始执行。
LauncherModel.java: 维护Launcher在内存中的状态,提供与数据库进行交互的API。
ShortcutAdapter.java: 显示添加快件方式对话框
UnstallShortcutReceiver.java: 卸载快捷方式的接听器。
Workspace.java: 所有屏幕的集合,实现主屏幕的拖动效果。
CellLayout.java: 代表桌面上的一屏。
三、Launcher应用程序列表内容读取过程
Launcher从onCreate函数开始执行,初始化了一些变量,调用mModel.startLoader函数进行读取工作,LauncherModel中定义了一个Loader类,该类负责读取应用程序信息,Loader类创建一个线程LoaderThread来进行数据库的读取操作,LoaderThread中调用loadAndBindWorkspace函数实现了从数据库中读取桌面上应用程序信息,根据快捷方式、组件和文件夹区分开来存储在不同的列表中,bindWorkspace函数用来将已经存储的列表赋给Launcher对象,同时在Workspace中添加并显示这些视图对象。loadAndBindAllApps函数用来读取所有安装的应用程序信息存入列表中,并将当前列表赋给Launcher中的AllAppsView对象。
四、Launcher中桌面的滚动
在桌面上,如果当前的事件是拖动事件,Workspace使用Scroller根据当前的移动的位置及距离进行桌面的移动效果。
五、Launcher桌面的点击事件
首先判断当前所点击的位置放置的是什么东西,如果是快捷方式则启动当前快捷方式所代表的应用程序,如果是文件夹则显示当前文件夹中存在的内容,如果是所有应用程序列表按钮,则显示所有的应用程列表,其他情况则不进行处理。
六、Launcher中的长按事件
如果当前长按的是桌面,则弹出添加到桌面对话框,如果有应用程序快捷方式,则根据当前的应用程序快捷方式创建一个DragView对象,当有移动事件时,移动当前的DragView对象,在拖动开始时删除区域会显示出来(DeleteZone设置为可见),当将图标拖入删除区域时,删除区域及DragView对象的背景颜色会改变,在删除区域中松开手可以实现将当前快捷方式从桌面上删除,图标离开删除区域时删除区域及DragView对象的背景会恢复成原来的样子。 在应用程序列表中,长按某个应用程序,则会关闭掉当前的应用程序列表,以后的拖动事件处理和在桌面上拖动应用程序快捷方式的效果是一样的。如果当前长按的是已打开文件夹的名字,则弹出更改文件夹名字对话框(如下图)。
七、Launcher中的拖动应用程序图标效果
Launcher中使用WindowManager进行应用程序快捷方式的拖动。整个Android的窗口机制是基于WindowManager的,这个接口可以添加View到屏幕,也可以从屏幕删除一个View,它面向的一端是屏幕,另一端是View,直接忽略了Activity或者Dialog等东西,WindowManager是全局的。附件是我写的一个例子。
源代码:
- package lzu.WindowManagerTest;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.PixelFormat;
- import android.os.Bundle;
- import android.view.Gravity;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.WindowManager;
- import android.widget.ImageView;
- public class WindowManagerTest extends Activity {
- /** Called when the activity is first created. */
- private float mPosX;
- private float mPosY;
- Bitmap bitmap;
- WindowManager.LayoutParams mWindowParams;
- WindowManager mWindowManager;
- ImageView v;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.button);
- addViewToWindowManage(bitmap, 200, 200);
- }
- public boolean onTouchEvent(MotionEvent motion){
- switch(motion.getAction()){
- case MotionEvent.ACTION_DOWN:
- mPosX = motion.getX();
- mPosY = motion.getY();
- return true;
- case MotionEvent.ACTION_MOVE:
- mPosX = motion.getX();
- mPosY = motion.getY();
- updateViewPosition(v, (int)mPosX,(int) mPosY);
- return true;
- case MotionEvent.ACTION_UP:
- removeView(v);
- return true;
- }
- return true;
- }
- void addViewToWindowManage(Bitmap bm, int x, int y) {
- mWindowParams = new WindowManager.LayoutParams();
- mWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
- mWindowParams.x = x;
- mWindowParams.y = y;
- mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
- mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
- mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
- | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
- mWindowParams.format = PixelFormat.TRANSLUCENT;
- mWindowParams.windowAnimations = 0;
- v = new ImageView(this);
- v.setImageBitmap(bm);
- mWindowManager = (WindowManager) this.getSystemService("window");
- mWindowManager.addView(v, mWindowParams);
- }
- void updateViewPosition(View v,int x,int y){
- mWindowParams.alpha = 1.0f;
- mWindowParams.x = x ;
- mWindowParams.y = y;
- mWindowManager.updateViewLayout(v, mWindowParams);
- }
- void removeView(View v){
- mWindowManager.removeView(v);;
- }
- }
代码包下载地址:http://download.csdn.net/source/3521066
效果截图为:
LauncherApplication中有变量,一个是LauncherModel,一个是IconCache。在本类中生成LauncherModel对象,作为全局使用的操作数据的对象,并且为Launcher注册了相应的广播,一种是package的remove,update,add,还有快捷方式的Observer,在有快捷方式的变动,重新load。IconCache,是为程序的快捷方式提供默认的图标。