对Android4.0中Launcher2一些调试记录

来源:互联网 发布:mac版pscc2018破解 编辑:程序博客网 时间:2024/06/05 06:40

最近项目打板了,板子跑起来后发现Launcher的所有程序界面不能全屏(两边有黑框,只在中上部显示),但是主界面看上去是全屏显示的(后面证实也非全屏显示。)

我们的屏是21寸的,分辨率为1980*1080。

最开始以为是uboot里的屏幕参数没设置好,后面check之后发现没问题。没办法,只有去看Launcher的代码。

首先,在我最开始就有一个误解,这个误解浪费我很多时间。由于最开始的时候主界面(也就是workspace)是没有黑框的,所以我一直认为workspace的代码是没问题的。

后面经验证主界面也没有按屏幕的实际分辨率显示!Workspace.java中构造函数有如下代码:

复制代码
 1 final float smallestScreenDim = res.getConfiguration().smallestScreenWidthDp; 2  cellCountX = 1; 3             while (CellLayout.widthInPortrait(res, cellCountX + 1) <= smallestScreenDim) { 4                  5                 cellCountX++; 6             } 7  8             cellCountY = 1; 9             while (actionBarHeight + CellLayout.heightInLandscape(res, cellCountY + 1)10                 <= smallestScreenDim - systemBarHeight) {11                 cellCountY++;12             }13         }
复制代码
smallestScreenDim 按字面理解意思应该是屏幕宽度的最小值(以DP为单位),cellCountX初始化为1,然后通过一个while循环去计算X、Y方向各能放多少个应用。我们看看widthInPortrait方法:
复制代码
1     static int widthInPortrait(Resources r, int numCells) {2         // We use this method from Workspace to figure out how many rows/columns Launcher should3         // have. We ignore the left/right padding on CellLayout because it turns out in our design4         // the padding extends outside the visible screen size, but it looked fine anyway.5         int cellWidth = r.getDimensionPixelSize(R.dimen.workspace_cell_width);6         int minGap = Math.min(r.getDimensionPixelSize(R.dimen.workspace_width_gap),7                 r.getDimensionPixelSize(R.dimen.workspace_height_gap));8         return minGap * (numCells - 1) + cellHeight * numCells;9     }
复制代码
getDimensionPixelSize方法实际上是把dimens.xml中设置的cellWidth大小由dp转换成px!
widthInPortrait计算后的返回值会与smallestScreenDim进行比较,如果比smallestScreenDim 小,那么说明能够再放一个APP,cellCount进行加一。循环比较之后就会得出在该屏幕上能放多少行,多少列个应用。既然cellWidth的单位为px,那与通过他计算后得到的值进行比较的smallestScreenDim单位应该也是px,而不是像他字面所说的dp!通过加log进一步确认,我发现android4.0默认的smallestScreenDim为720!也就是720px,而我的屏实际像素宽度为1920!将smallestScreenDim强制设置为1920后all apps界面能全屏了,主界面的workspace也大了很多!说明之前主界面的全屏都是假象。。。我们可以在代码里得到屏幕的宽度,然后赋值给smallestScreenDim以便于支持更多的屏幕。至于之前的主界面为什么没有黑色的边框,我估计是壁纸设置的原因,具体细节没去深究了。后面发现系统默认的图标在大屏幕上显示效果不太好,有点偏小,直接修改res/values-sw600dp/dimens.xml中的app_icon_size。改完make之后发现图标并没有变大。。。跟踪代码Launcher.java[onCreate]--->[setLauncher]--->LauncherApplication[onCreate]--->[new LauncherModel]--->[createIconBitmap]
复制代码
  1 static Bitmap createIconBitmap(Drawable icon, Context context) {  2         synchronized (sCanvas) { // we share the statics :-(  3             if (sIconWidth == -1) {  4                 initStatics(context);  5             }  6   7             int width = sIconWidth;  8             int height = sIconHeight;  9              10             Log.i("Info","In createIconBitmap width is: "+width); 11             Log.i("Info","In createIconBitmap height is: "+height); 12             if (icon instanceof PaintDrawable) { 13                 Log.i("Info","Icon type is PaintDrawable" ); 14                 PaintDrawable painter = (PaintDrawable) icon; 15                 painter.setIntrinsicWidth(width); 16                 painter.setIntrinsicHeight(height); 17             } else if (icon instanceof BitmapDrawable) { 18                 // Ensure the bitmap has a density. 19                 Log.i("Info","Icon type is BitmapDrawable" ); 20                 BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; 21                 Bitmap bitmap = bitmapDrawable.getBitmap(); 22                 if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { 23                     bitmapDrawable.setTargetDensity(context.getResources().getDisplayMetrics()); 24                 } 25             } 26             int sourceWidth = icon.getIntrinsicWidth(); 27             int sourceHeight = icon.getIntrinsicHeight(); 28             Log.i("Info","IntrinsicWidth is: "+sourceWidth); 29             Log.i("Info","IntrinsicHeight is: "+sourceHeight); 30             if (sourceWidth > 0 && sourceHeight > 0) { 31                 // There are intrinsic sizes. 32                 if (width < sourceWidth || height < sourceHeight) { 33                     // It's too big, scale it down. 34                     final float ratio = (float) sourceWidth / sourceHeight; 35                     if (sourceWidth > sourceHeight) { 36                         height = (int) (width / ratio); 37                     } else if (sourceHeight > sourceWidth) { 38                         width = (int) (height * ratio); 39                     } 40                 } else if (sourceWidth < width && sourceHeight < height) { 41                     // Don't scale up the icon 42                     //width = sourceWidth; 43                     //height = sourceHeight; 44                     width = sIconWidth; 45                     height = sIconHeight; 46                 } 47             } 48  49             // no intrinsic size --> use default size 50             int textureWidth = sIconTextureWidth; 51             int textureHeight = sIconTextureHeight; 52             Log.i("Info","textureWidth is: "+textureWidth); 53             Log.i("Info","textureHeight is: "+textureHeight); 54  55             final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight, 56                     Bitmap.Config.ARGB_8888); 57             final Canvas canvas = sCanvas; 58             canvas.setBitmap(bitmap); 59  60             final int left = (textureWidth-width) / 2; 61             final int top = (textureHeight-height) / 2; 62  63             if (false) { 64                 // draw a big box for the icon for debugging 65                 canvas.drawColor(sColors[sColorIndex]); 66                 if (++sColorIndex >= sColors.length) sColorIndex = 0; 67                 Paint debugPaint = new Paint(); 68                 debugPaint.setColor(0xffcccc00); 69                 canvas.drawRect(left, top, left+width, top+height, debugPaint); 70             } 71  72             sOldBounds.set(icon.getBounds()); 73             icon.setBounds(left, top, left+width, top+height); 74             icon.draw(canvas); 75             icon.setBounds(sOldBounds); 76             canvas.setBitmap(null); 77  78             return bitmap; 79         } 80     } 81 private static void initStatics(Context context) { 82         final Resources resources = context.getResources(); 83         final DisplayMetrics metrics = resources.getDisplayMetrics(); 84         final float density = metrics.density; 85  86         //default is 72*density 87         sIconWidth = sIconHeight = (int) resources.getDimension(R.dimen.app_icon_size); 88         sIconTextureWidth = sIconTextureHeight = sIconWidth; 89  90         sBlurPaint.setMaskFilter(new BlurMaskFilter(5 * density, BlurMaskFilter.Blur.NORMAL)); 91         sGlowColorPressedPaint.setColor(0xffffc300); 92         sGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 93         sGlowColorFocusedPaint.setColor(0xffff8e00); 94         sGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); 95  96         ColorMatrix cm = new ColorMatrix(); 97         cm.setSaturation(0.2f); 98         sDisabledPaint.setColorFilter(new ColorMatrixColorFilter(cm)); 99         sDisabledPaint.setAlpha(0x88);100     }
复制代码
经过分析,发现在这个方法里对图片大小进行了判断,如果大于默认的图片大小96dp,那么强制将图片大小设置为96dp!稍作修改图标就能放大了,细节不说了,大家看看代码就知道了。http://www.cnblogs.com/leon19870907/archive/2012/04/20/2459593.html
原创粉丝点击