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

最近项目打板了,板子跑起来后发现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 should
3         // have. We ignore the left/right padding on CellLayout because it turns out in our design
4         // 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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值