1、获取LauncherAppState实例:
LauncherAppState app = LauncherAppState.getInstance();
LauncherAppState这个类主要做了些什么呢?
从这个类的构造方法中可以发现,做了些初始化的操作:
(1)初始化LauncherModel、IconCache、WidgetCache、InvariantDeviceProfile等。
(2)注册广播:
//手机环境变化比如语言横竖屏之类
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
//搜索管理相关的变化
filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
// For handling managed profiles
filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED);
filter.addAction(LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED);
2、初始化DeviceProfile:
mDeviceProfile = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE ?
app.getInvariantDeviceProfile().landscapeProfile
: app.getInvariantDeviceProfile().portraitProfile;
那么这个类主要做了些什么呢?
(1)定义了Launcher的很多属性,比如图标的大小、间距;
(2)可用间距发生改变时调用updateIconSize方法,重新计算更新图标大小:行列数是根据配置的行列数、图标大小、表格间距等计算出来的。如果想要改变行列数,可以适当的把图标缩小放大、间距加大或减小。
3、获取SharedPreferences实例
mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),Context.MODE_PRIVATE);
4、获取LauncherModel实例:
mModel = app.setLauncher(this);
LuancherModel是操作数据相关的类,保存了桌面运行的状态,加载桌面数据。
5、获取IconCache实例:
mIconCache = app.getIconCache();
这个类主要是保存图标信息,保存图标信息的方法是cacheLocked这个方法,可在此方法修改图标信息。
6、获取DragController实例:
mDragController = new DragController(this);
这是一个处理拖动图标的类,提供了一个内部接口:
public interface DragListener{
//拖动图标开始时执行的方法
void onDragStart(DragSource source, Object info, int dragAction);
//拖动图标结束时执行的方法
void onDragEnd();
}
7、获取AppWidgetManager实例,用来管理widget
mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
8、setContentView(R.layout.launcher)设置布局
9、setupViews 初始化控件,注册点击监听等,分析主要的地方,代码太多不贴完整的
private void setupViews() {
//具体的拖曳处理是在DragController
final DragController dragController = mDragController;
mLauncherView = findViewById(R.id.launcher);
mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);
//draglayer是桌面的最外层,是一个viewgroup,继承InsettableFrameLayout,具体的拖曳处理交给draglayercontroller
mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);
//页面切换监听
mWorkspace.setPageSwitchListener(this);
//指示当前页面的圆点
mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);
mLauncherView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
//workspace背景图片
mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);
// Setup the drag layer
//把draglayer和dragcontroller关联起来
mDragLayer.setup(this, dragController);
// Setup the hotseat
mHotseat = (Hotseat) findViewById(R.id.hotseat);
if (mHotseat != null) {
mHotseat.setOnLongClickListener(this);
}
//OverviewPanel预览,长按屏幕会进入预览模式
mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);
mWidgetsButton = findViewById(R.id.widget_button);
mWidgetsButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (!mWorkspace.isSwitchingState()) {
onClickAddWidgetButton(arg0);
}
}
});
mWidgetsButton.setOnTouchListener(getHapticFeedbackTouchListener());
View wallpaperButton = findViewById(R.id.wallpaper_button);
wallpaperButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (!mWorkspace.isSwitchingState()) {
onClickWallpaperPicker(arg0);
}
}
});
wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());
View settingsButton = findViewById(R.id.settings_button);
if (hasSettings()) {
settingsButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (!mWorkspace.isSwitchingState()) {
onClickSettingsButton(arg0);
}
}
});
settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
} else {
settingsButton.setVisibility(View.GONE);
}
//设置透明度
mOverviewPanel.setAlpha(0f);
// Setup the workspace
mWorkspace.setHapticFeedbackEnabled(false);
mWorkspace.setOnLongClickListener(this);
//workspace建立控制器的控制
mWorkspace.setup(dragController);
//设置workspace的拖曳事件
dragController.addDragListener(mWorkspace);
// Get the search/delete bar
//获取搜索框或删除
mSearchDropTargetBar = (SearchDropTargetBar)
mDragLayer.findViewById(R.id.search_drop_target_bar);
// Setup Apps and Widgets
//初始化小部件、app
mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);
mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);
if (mLauncherCallbacks != null && mLauncherCallbacks.getAllAppsSearchBarController() != null) {
mAppsView.setSearchBarController(mLauncherCallbacks.getAllAppsSearchBarController());
} else {
mAppsView.setSearchBarController(mAppsView.newDefaultAppSearchController());
}
// Setup the drag controller (drop targets have to be added in reverse order in priority)
dragController.setDragScoller(mWorkspace);
dragController.setScrollView(mDragLayer);
dragController.setMoveTarget(mWorkspace);
dragController.addDropTarget(mWorkspace);
if (mSearchDropTargetBar != null) {
mSearchDropTargetBar.setup(this, dragController);
mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());
}
if (getResources().getBoolean(R.bool.debug_memory_enabled)) {
Log.v(TAG, "adding WeightWatcher");
//钟表组件
mWeightWatcher = new WeightWatcher(this);
mWeightWatcher.setAlpha(0.5f);
((FrameLayout) mLauncherView).addView(mWeightWatcher,
new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.BOTTOM)
);
boolean show = shouldShowWeightWatcher();
mWeightWatcher.setVisibility(show ? View.VISIBLE : View.GONE);
}
}
这个方法里涉及了拖动图标的操作,建立了层层联系。DragLayer、DragController、DragSource、DragTarget、DragScroller、DragView这几个类之间的联系需要理清楚(如何联系):
DragLayer:是一个协调处理它的子View的拖动的容器,它的布局在Launcher是最外层的布局
DragController:这是一个处理拖动图标的类。
DragSource:这是一个接口,拖动源,实现这个接口的两个类:AppsCustomizedPagedView 和Workspace
DragTarget:这是一个接口,是一个可以放置被拖动对象的容器, 实现了这个接口的有ButtonDropTarget、Folder、Workpsace三个 。它内部定义了一个DragObject类,声明一些与拖动相关的属性。
DragScroller是一个接口,控制滑动,左滑、右滑、进入滑动区域、退出滑动区域
DragView:拖动的view
Workspace实现了DropTarget、DragSource、DragScroller以及DragController.DragListener这些接口
public class Workspace extends PagedView
implements DropTarget, DragSource, DragScroller, View.OnTouchListener,
DragController.DragListener, LauncherTransitionable, ViewGroup.OnHierarchyChangeListener,
Insettable, UninstallSource, AccessibilityDragSource, Stats.LaunchSourceProvider {
在setupViews方法中
mDragLayer.setup(this, dragController);
mWorkspace.setup(dragController);
//设置拖曳事件
dragController.addDragListener(mWorkspace);
// Setup the drag controller (drop targets have to be added in reverse order in priority)
dragController.setDragScoller(mWorkspace);
dragController.setScrollView(mDragLayer);
dragController.setMoveTarget(mWorkspace);
dragController.addDropTarget(mWorkspace);
if (mSearchDropTargetBar != null) {
//搜索/删除框建立拖动关系
mSearchDropTargetBar.setup(this, dragController);
mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());
}
在Launcher类的public boolean onLongClick(View v)方法中,开始图标的拖动操作
mWorkspace.startDrag(longClickCellInfo);
// TODO: This method should be a part of LauncherSearchCallback
public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {
dragView.setTag(dragInfo);
mWorkspace.onExternalDragStartedWithItem(dragView);
mWorkspace.beginExternalDragShared(dragView, source);
}
拖动图标的流程:
1、Launcher.onLongClick;
2、Workspace.startDrag;
3、Workspace.onExternalDragStartedWithItem(dragView)
4、beginExternalDragShared(dragView, source);
6、DragController.startDrag;
7、DragController.handleMoveEvent
8、DragController.checkTouchMove
9、DragController.checkScrollState
10、DragController.onTouchEvent
10、设置这些控件的位置摆放(searbar、hotseat、workspace、pageindicator、overviewmode)
mDeviceProfile.layout(this);
11、加载桌面图标,widget等,调用LauncherMode的startLoader方法进行加载
mModel.startLoader()
12、处理默认键
mDefaultKeySsb = new SpannableStringBuilder();
Selection.setSelection(mDefaultKeySsb, 0);
13、注册广播,监听关闭系统对话框
IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(mCloseSystemDialogsReceiver, filter);
14、第一次运行的时候提示帮助信息。
//显示介绍界面
showIntroScreen();
//显示帮助界面
showFirstRunActivity();
//显示帮助信息
showFirstRunClings();
15、初始化默认壁纸
initDefaultWallpaperResourceId();