在做完仿小米桌面之后,客户又提了一个新需求,要求安装APK的时候,快捷方式要出现在末尾空白位置 仿小米桌面方法请点击:Launcher3仿小米桌面
在代码中开始搜索之旅 在这个位置packages\apps\Launcher3\src\com\android\launcher3\LauncherModel.java
发现了一个findNextAvailableIconSpace方法
// Try adding to the workspace screens incrementally, starting at the default or center
// screen and alternating between +1, -1, +2, -2, etc. (using ~ ceil(i/2f)*(-1)^(i-1))
firstScreenIndex = Math.max(firstScreenIndex, workspaceScreens.size()); //czy min
int count = workspaceScreens.size();
for (int screen = firstScreenIndex - 1; screen < count && !found; screen++) { //czy 加-1
int[] tmpCoordinates = new int[2];
if (findNextAvailableIconSpaceInScreen(items, tmpCoordinates,
workspaceScreens.get(screen))) {
// Update the Launcher db
return new Pair<Long, int[]>(workspaceScreens.get(screen), tmpCoordinates);
}
}
}
return null;
}
这里说明先for (int screen = firstScreenIndex - 1; screen < count && !found; screen++)在找第几屏,如果没有就新建一个 具体增加快捷方式坐标得方法在这里
findNextAvailableIconSpaceInScreen(items, tmpCoordinates,workspaceScreens.get(screen)
tmpCoordinates这个参数就是快捷方式插入的位置
源代码原有的方法是从上到下 从左到右的顺序去遍历每一个位置 遇到空位就插进去 具体方法如下
static boolean findNextAvailableIconSpaceInScreen(ArrayList<ItemInfo> items, int[] xy,
long screen) {
int a = 0;
int b = 0;
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
final int xCount = (int) grid.numColumns;
final int yCount = (int) grid.numRows;
boolean[][] occupied = new boolean[xCount][yCount];
//czy
ArrayList<Integer> myX = new ArrayList<Integer>();
ArrayList<Integer> myY = new ArrayList<Integer>();
//end
int cellX, cellY, spanX, spanY;
for (int i = 0; i < items.size(); ++i) {
final ItemInfo item = items.get(i);
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
if (item.screenId == screen) {
cellX = item.cellX;
cellY = item.cellY;
spanX = item.spanX;
spanY = item.spanY;
for (int x = cellX; 0 <= x && x < cellX + spanX && x < xCount; x++) {
for (int y = cellY; 0 <= y && y < cellY + spanY && y < yCount; y++) {
occupied[x][y] = true;
}
}
//czy
for (int y = 0; y < yCount; y++) {
for (int x = 0; x < xCount; x++) {
if(occupied[x][y]){
myX.add(x);
myY.add(y);
}
}
}
//end
}
}
}
return CellLayout.findVacantCellCzy(xy, 1, 1, xCount, yCount, occupied, myX, myY);//czy
}
可以看到 返回的又是一个方法加参数 这个方法是重写的,直接给出路径和具体代码
路径packages\apps\Launcher3\src\com\android\launcher3\CellLayout.java
static boolean findVacantCellCzy(int[] vacant, int spanX, int spanY,
int xCount, int yCount, boolean[][] occupied, ArrayList<Integer> myX, ArrayList<Integer> myY) {
ArrayList<Integer> myXX = new ArrayList<Integer>();
int xC = 0;
int yC = 0;
if(myX.size() >=1 && myY.size()>=1){
xC = myX.get(myX.size()-1);
yC = myY.get(myY.size()-1);
}
for (int y = yC; y < yCount; y++) {
for (int x = xC; x < xCount; x++) {
boolean available = !occupied[x][y];
out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
for (int j = y; j < y + spanY - 1 && y < yCount; j++) {
available = available && !occupied[i][j];
if (!available) break out;
}
}
if (available) {
if(x == 3 /*&& occupied[x][y - 1]*/){
for(int z = 0; z < xCount; z++){
if(!occupied[z][y]){
myXX.add(z);
}
}
if(myXX.size() == 4){
x = myXX.get(0);
}else{
if(myXX.size() != 0){
x = myXX.get(myXX.size() - 1);
}
}
Log.i("czy","-----x------"+x);
}
vacant[0] = x;
vacant[1] = y;
return true;
}
}
}
return false;
}
//end
最后把原生代码也贴出来,更直观
static boolean findVacantCell(int[] vacant, int spanX, int spanY,
int xCount, int yCount, boolean[][] occupied) {
for (int y = 0; y < yCount; y++) {
for (int x = 0; x < xCount; x++) {
boolean available = !occupied[x][y];
out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
for (int j = y; j < y + spanY - 1 && y < yCount; j++) {
available = available && !occupied[i][j];
if (!available) break out;
}
}
if (available) {
vacant[0] = x;
vacant[1] = y;
return true;
}
}
}
return false;
}