版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a396604593/article/details/82586143
负一屏整体框架
目录
负一屏创建时机
负一屏的创建在Launcher.java的bindScreens中,该方法:
1、bindAddScreens传入一个界面列表,循环往workspace中添加需要的界面
2、判断是否需要添加左屏(也就是负一屏),如果需要则在workspace.java的createCustomContentContainer中完成该页面的添加。
populateCustomContentContainer中完成页面内容的填充。
@Override
public void bindScreens(ArrayList<Long> orderedScreenIds) {
bindAddScreens(orderedScreenIds);
// If there are no screens, we need to have an empty screen
if (orderedScreenIds.size() == 0) {
mWorkspace.addExtraEmptyScreen();
}
// Create the custom content page (this call updates mDefaultScreen which calls
// setCurrentPage() so ensure that all pages are added before calling this).
if (needCustomContentToLeft()) {
mWorkspace.createCustomContentContainer();
populateCustomContentContainer();
}
}
1、workspace页面顺序
bindAddScreens中,循环添加页面
@Override
public void bindAddScreens(ArrayList<Long> orderedScreenIds) {
int count = orderedScreenIds.size();
for (int i = 0; i < count; i++) {
mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));
}
}
public long insertNewWorkspaceScreenBeforeEmptyScreen(long screenId) {
// Find the index to insert this view into. If the empty screen exists, then
// insert it before that.
int insertIndex = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID);
if (insertIndex < 0) {
insertIndex = mScreenOrder.size();
}
return insertNewWorkspaceScreen(screenId, insertIndex);
}
public long insertNewWorkspaceScreen(long screenId, int insertIndex) {
if (mWorkspaceScreens.containsKey(screenId)) {
throw new RuntimeException("Screen id " + screenId + " already exists!");
}
// Inflate the cell layout, but do not add it automatically so that we can get the newly
// created CellLayout.
CellLayout newScreen = (CellLayout) mLauncher.getLayoutInflater().inflate(
R.layout.workspace_screen, this, false /* attachToRoot */);
//Added by ****** in 2017-6-26 for drag icon InOverviewMode(bug)
if (isInOverviewMode() && !mLauncher.isEditing()) {
newScreen.getPageSetting().setVisibility(VISIBLE);
}
//Added by ****** in 2017-6-26for drag icon InOverviewMode(bug)
newScreen.setOnLongClickListener(mLongClickListener);
newScreen.setOnClickListener(mLauncher);
newScreen.setSoundEffectsEnabled(false);
mWorkspaceScreens.put(screenId, newScreen);
mScreenOrder.add(insertIndex, screenId);
addView(newScreen, insertIndex);//添加view到指定的下标
changePageSettingColor();
LauncherAccessibilityDelegate delegate =
LauncherAppState.getInstance().getAccessibilityDelegate();
if (delegate != null && delegate.isInAccessibleDrag()) {
newScreen.enableAccessibleDrag(true, CellLayout.WORKSPACE_ACCESSIBILITY_DRAG);
}
return screenId;
}
这样就完成了workspace的页面添加。
2、负一屏的加入和view的填充
负一屏页面的添加:mWorkspace.createCustomContentContainer();
public void createCustomContentContainer() {
CellLayout customScreen = (CellLayout)
mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, this, false);
customScreen.disableDragTarget();
customScreen.disableJailContent();
mWorkspaceScreens.put(CUSTOM_CONTENT_SCREEN_ID, customScreen);
mScreenOrder.add(0, CUSTOM_CONTENT_SCREEN_ID);
// We want no padding on the custom content
customScreen.setPadding(0, 0, 0, 0);
//负一屏边距
if (mLauncher!=null&&mLauncher.needCustomContentToLeft()){
CustomPageManager.getInstance(mLauncher).setInsets(insetsRealSize);
}
addFullScreenPage(customScreen);//添加到workspace
// Ensure that the current page and default page are maintained.
// Added by huanghaihao in 2017-6-26 for screen setting start
int pageIndex = getPageIndexForScreenId(mDefaultPageScreenId);
if (-1 != pageIndex) {
mDefaultPage = pageIndex;
} else {
mDefaultPage = mOriginalDefaultPage + 1;
}
// Added by huanghaihao in 2017-6-26 for screen setting end
// Update the custom content hint
if (mRestorePage != INVALID_RESTORE_PAGE) {
mRestorePage = mRestorePage + 1;
} else {
setCurrentPage(getCurrentPage() + 1);
}
}
以上可以看出,addFullScreenPage方法决定了添加动作。方法体内部,固定的把负一屏添加到了首位:
public void addFullScreenPage(View page) {
LayoutParams lp = generateDefaultLayoutParams();
lp.isFullScreenPage = true;
super.addView(page, 0, lp);//添加view到指定的下标
}
负一屏view的填充:populateCustomContentContainer();
protected void populateCustomContentContainer() {
//if (mLauncherCallbacks != null) {
// mLauncherCallbacks.populateCustomContentContainer();
//}
//负一屏view
View customView = CustomPageManager.getInstance(null).getCustomPageView();
Log.i(TAG, "populateCustomContentContainer customView="+customView);
addToCustomContentPage(customView,null,"");
}
以上,添加view到负一屏的页面,可以看出,view的实现根据产品的界面。最简单的 new情况,一个textview也能看到效果。负一屏的本质其实就是一个view。
public void addToCustomContentPage(View customContent, Launcher.CustomContentCallbacks callbacks,
String description) {
if (getPageIndexForScreenId(CUSTOM_CONTENT_SCREEN_ID) < 0) {
throw new RuntimeException("Expected custom content screen to exist");
}
// Add the custom content to the full screen custom page
CellLayout customScreen = getScreenWithId(CUSTOM_CONTENT_SCREEN_ID);
int spanX = customScreen.getCountX();
int spanY = customScreen.getCountY();
CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, spanX, spanY);
lp.canReorder = false;
lp.isFullscreen = true;
if (customContent instanceof Insettable) {
((Insettable) customContent).setInsets(mInsets,insetsRealSize);
}
// Verify that the child is removed from any existing parent.
if (customContent.getParent() instanceof ViewGroup) {
ViewGroup parent = (ViewGroup) customContent.getParent();
parent.removeView(customContent);
}
customScreen.removeAllViews();
customContent.setFocusable(true);
customContent.setOnKeyListener(new FullscreenKeyEventListener());
//delete by linhai remove focusChange start 31/8/2017
// customContent.setOnFocusChangeListener(mLauncher.mFocusHandler
// .getHideIndicatorOnFocusListener());
//delete by linhai remove focusChange start 31/8/2017
customScreen.addViewToCellLayout(customContent, 0, 0, lp, true);
mCustomContentDescription = description;
mCustomContentCallbacks = callbacks;
if (mLauncher != null && mLauncher.needCustomContentToLeft()){
CustomPageManager.getInstance(mLauncher).addCustomPageComplete();
}
}
至于一层一层add,workspace中add Celllayout,Celllayout中add ShortcutAndWidgetContainer,ShortcutAndWidgetContainer最后addCustompageView。
都是Launcher结构的套路。其本质就是viewGroup的addView,因为workspace、Celllayout、ShortcutAndWidgetContainer都是viewGroup的子类。