1-问题摘要
这次主要解决困扰了我很久的时钟消失问题,大概是去年10月刚开始做EDLA项目的时候,需要定制谷歌桌面,桌面布局大概要改成这样:
时间显示在谷歌搜索框的上方,而安卓原生桌面大概是这样子的
我们开发一开始是使用小部件的方式加载谷歌时钟显示在桌面,而我们知道,桌面显示的任何组件都是以行和列的形式存在的,当时我们想要改时间为2行3列才能达到预期效果,但是奇怪的是2行3列的时间小部件在开机后并没有显示出来,暂时找不到原因只好使用1行3列布局,大概长这样
无论是默认定义2行或者是手动调整到2行,重启后时钟都会消失.
二-解决方法
先贴解决方法吧,原因分析写在后面,想看就看
小部件消失一般是跟谷歌搜索框有关,修改路径为Launcher3目录下的src/com/android/launcher3/model/LoaderCursor.java
找到这个方法
/*** check & update map of what's occupied; used to discard overlapping/invalid items*/protected boolean checkItemPlacement(ItemInfo item) {int containerIndex = item.screenId;if (item.container == Favorites.CONTAINER_HOTSEAT) {final GridOccupancy hotseatOccupancy =mOccupied.get(Favorites.CONTAINER_HOTSEAT);if (item.screenId >= mIDP.numDatabaseHotseatIcons) {Log.e(TAG, "Error loading shortcut " + item+ " into hotseat position " + item.screenId+ ", position out of bounds: (0 to " + (mIDP.numDatabaseHotseatIcons - 1)+ ")");return false;}if (hotseatOccupancy != null) {if (hotseatOccupancy.cells[(int) item.screenId][0]) {Log.e(TAG, "Error loading shortcut into hotseat " + item+ " into position (" + item.screenId + ":" + item.cellX + ","+ item.cellY + ") already occupied");return false;} else {hotseatOccupancy.cells[item.screenId][0] = true;return true;}} else {final GridOccupancy occupancy = new GridOccupancy(mIDP.numDatabaseHotseatIcons, 1);occupancy.cells[item.screenId][0] = true;mOccupied.put(Favorites.CONTAINER_HOTSEAT, occupancy);return true;}} else if (item.container != Favorites.CONTAINER_DESKTOP) {// Skip further checking if it is not the hotseat or workspace containerreturn true;}final int countX = mIDP.numColumns;final int countY = mIDP.numRows;if (item.container == Favorites.CONTAINER_DESKTOP && item.cellX < 0 || item.cellY < 0|| item.cellX + item.spanX > countX || item.cellY + item.spanY > countY) {Log.e(TAG, "Error loading shortcut " + item+ " into cell (" + containerIndex + "-" + item.screenId + ":"+ item.cellX + "," + item.cellY+ ") out of screen bounds ( " + countX + "x" + countY + ")");return false;}if (!mOccupied.containsKey(item.screenId)) {GridOccupancy screen = new GridOccupancy(countX + 1, countY + 1);if (item.screenId == Workspace.FIRST_SCREEN_ID && FeatureFlags.QSB_ON_FIRST_SCREEN) {// Mark the first X columns (X is width of the search container) in the first row as// occupied (if the feature is enabled) in order to account for the search// container.int spanX = mIDP.numSearchContainerColumns;int spanY = 1;screen.markCells(0, 0, spanX, spanY, true);}mOccupied.put(item.screenId, screen);}final GridOccupancy occupancy = mOccupied.get(item.screenId);// Check if any workspace icons overlap with each otherif (occupancy.isRegionVacant(item.cellX, item.cellY, item.spanX, item.spanY)) {occupancy.markCells(item, true);return true;} else {Log.e(TAG, "Error loading shortcut " + item+ " into cell (" + containerIndex + "-" + item.screenId + ":"+ item.cellX + "," + item.cellX + "," + item.spanX + "," + item.spanY+ ") already occupied");return false;}}
这个方法用来判断加载的组件相互之间是否存在布局重叠,如果有布局重叠,则不加载相应的组件
这行代码标记了谷歌搜索框的位置,从第1行第一列开始,占据spanX列和spanY行的空间,一般spanX在配置文件里定义为5,spanY为1,所以桌面的第一行基本是谷歌搜索框的天下,解决办法要根据你主布局是否需要搜索框来改:
1.如果你的布局不需要谷歌搜索框,就直接把screen.markCells(0, 0, spanX, spanY, true);给注释掉;
2.需要谷歌搜索框的话,就需要保持你桌面搜索框显示的位置和这里一致,查看src/com/android/launcher3/Workspace.java的bindAndInitFirstWorkspaceScreen()方法,里面定义了谷歌搜索框的位置
比如我这里定义居中的是从第二行第一列开始,占据5列1行空间,所以要把screen.markCells(0, 0, spanX, spanY, true);改为screen.markCells(1, 2, 5, 1, true);
这样改了之后就不会计算出组件布局重叠区域了,可以正常显示衍生到桌面第一行的小部件,不单单是时钟组件.
三-原理分析
首先分析桌面启动加载小部件流程…未完待续