要想使自己的布局在不同设备达到精准空置,理清理顺android布局长度单位之间关系很有必要,否则你也许会经常挠头为什么显示出来的布局不是自己定义的效果呢,有些东西,虽然基础,但是弄个透彻也需要花些功夫,废话不多说,下面开始。
1.先了解一下android有支持哪些长度单位:
px: pixels(像素). 不同设备显示效果相同,比如我们800*480的屏幕宽度就是 800px
dip: device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,通常屏幕大时,density就大,屏幕小时,density就小
屏幕实际分辨率为240px*400px时,densityDpi=120
屏幕实际分辨率为320px*533px,densityDpi=160
屏幕实际分辨率为480px*800px,densityDpi=240
而dip与px之间的换算关系是:
pixs =dips * (densityDpi/160),也就是说当densityDpi=160时,1dip=1px
sp: scaled pixels(放大像素),sp的大小取决于系统metrics.scaledDensity值大小
pt: point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业(基本用不到)
pt与px的换算关系:pixs = pt*xdpi * (1.0f/72);xdpi表示1英寸像素个数
in(英寸)长度单位(基本用不到)
in与px的换算关系:pixs = in*xdpi
mm(毫米)长度单位(基本用不到)
mm与px的换算关系:pixs = mm * xdpi * (1.0f/25.4f)
2.看了上面具体长度单位的含义你会产生一个疑问,不同单位换算取决于系统的一些属性,比如densityDpi的值,xdpi的值,那么系统这些值在哪里获取了,直接看我写的测试用例:
public void testgetdisplay(){
WindowManager wm = (WindowManager) this.getInstrumentation().getContext().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(mDisplayMetrics);
System.out.println("display.height="+wm.getDefaultDisplay().getHeight());
System.out.println("display.width="+wm.getDefaultDisplay().getWidth());
System.out.println("densityDpi="+mDisplayMetrics.densityDpi);
System.out.println("xdpi="+mDisplayMetrics.xdpi);
System.out.println("density="+mDisplayMetrics.density);
}
3.densityDpi与drawable-(hdpi,mdpi,ldpi)之间的关系
系统drawable有hdpi,mdpi,ldpi三个文件夹下面存放不同尺寸的图片,使用哪个文件下的文件,与系统densityDpi值是有关系的
densityDpi=120:ldpi
densityDpi=160:mdpi
densityDpi=240:hdpi
前面我又说过densityDpi取决于显示屏,这样你就了解了为什么不同显示屏WVGA,HVGA,QVGA会采用不同drawable-(hdpi,mdpi,ldpi)图片
分辨率为240px*400px,densityDpi=120-->QVGA:ldpi
分辨率为320px*533px,densityDpi=160 -->HVGA:mdpi
分辨率为480px*800px,densityDpi=240 -->WVGA:WVGA
4.尽管了解上面这些理论值,但是有时候发现设置了不同长度单位,可显示出来的效果却出人预想,我曾经就碰到过这种挠头的问题,为解决这个问题,只有
深入代码,一探究竟了。
在深入代码前我们首先要搞清楚一个问题,那就是代码中所有长度值的单位都是px,
手上没有现成的例子就以现在我研究的/Launcher2/res/layout-land/workspace_screen.xml为例,看一个自定义属性:
launcher:cellWidth="105pt"
该属性自定义了一个桌面快捷图标的宽度,若读者自己测试,自己写个测试view,设置属性
android:layout_width="800px"
是一样的。
当view 被创建的时候,xml中的属性值存在参数AttributeSet attrs中
public CellLayout(Context context, AttributeSet attrs, int defStyle)
继续看该构造函数的实现代码
public CellLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//获取自定义属性组CellLayout中的所有自定义属性,关于自定义属性,这里不作展开说明
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
//获取属性cellWidth的值,长度单位将转换为px
mCellWidth = a.getDimensionPixelSize(R.styleable.CellLayout_cellWidth, 10);
。。。
}
实现长度单位换算的关键代码就在a.getDimensionPixelSize(R.styleable.CellLayout_cellWidth, 10),直接深入到关键代码:
public int getDimensionPixelSize(int index, int defValue)
public static int complexToDimensionPixelSize(int data,DisplayMetrics metrics)
public static float applyDimension(int unit, float value,DisplayMetrics metrics){
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
unit就是指单位类型,这个怎么来的我没有,但我想它肯定是在解析xml是根据不同单位转换的。
内容就这些,希望对你有用,欢迎拍砖!
分享到:
相关推荐
在Android平台上,这样的应用可以帮助用户方便地进行长度、重量、体积、温度等各类计量单位之间的换算。源码通常包含应用程序的所有逻辑和界面设计,对于学习Android开发或者想要定制自己单位换算应用的人来说,这是...
通过深入研究“android自动适应屏幕源码”中的代码实现,开发者可以学习如何结合上述技术,为自己的应用创建一个真正跨屏幕尺寸的适配方案。同时,“源码说明.txt”文件应提供了关于代码实现的详细解释,帮助理解每...
【贪吃蛇Android代码】项目是一个经典的移动游戏开发实例,主要使用了Android Studio作为集成开发环境,...通过深入研究并实践这个项目,开发者能够掌握Android应用开发的基本技能,并为今后的复杂项目打下坚实基础。
在Android应用开发中,本地化和国际化是两个重要的概念,它们涉及到如何使应用程序适应不同语言和地区的需求。...通过研究源码,可以深入理解如何在Android应用中实现对不同语言和文化的适应,提升应用的全球适用性。
【Android 简单刻度尺】是一款针对Android平台开发的简单刻度尺应用,它主要功能是...通过研究和理解这个项目的源码,开发者可以深入理解Android图形绘制、事件处理和动画机制,为自己的应用开发增添更多创新的可能性。
在Android平台上,开发一款体重计算应用涉及到多个技术层面和组件的使用。这个"Android体重计算源码.zip"可能包含了一个...如果你深入研究这些源码,你将能够看到一个完整的Android应用是如何从概念到实现的全过程。
通过深入研究这个源码,开发者不仅可以学会如何构建一个基础的登录界面,还能了解到Android应用开发中的许多最佳实践和常见技巧。同时,这也是一个很好的起点,可以在此基础上添加更多功能,如第三方登录、验证码...
HenCoder是一个广受欢迎的Android开发学习资源,它提供了许多深入的技术教程,帮助开发者掌握高级Android技能。 这个自定义刻度尺控件(Tape_Hencoder)旨在提供灵活的样式配置,允许开发者调整刻度的间距、颜色、...
在Android开发中,本地化(Localization)和国际化(Internationalization,简称i18n)是两个重要的概念...通过深入学习和研究这个Demo,开发者可以掌握如何使自己的应用具备全球化的适应性,满足不同地区用户的需求。
以上只是部分关键知识点,实际开发过程中还需要结合具体需求和设计进行深入研究。对于初学者来说,这是一个很好的实践项目,可以全面锻炼到Android开发的各项技能。而对于有经验的开发者,这则是一个展示技术和创新...
《安卓转换应用——Java编程实现单位转换》 在数字化时代,单位转换已成为日常生活和...通过深入研究这个项目,开发者不仅可以学习到基础的Android应用开发,还能进一步提升在Java编程和移动应用设计上的专业技能。
《Android Studio项目:深入探索照片应用与单位转换器》 Android Studio是Google为Android开发者提供的一个集成开发环境(IDE),它极大地简化了Android应用的构建、调试和发布流程。本项目集包含两个应用:照片...
《Android 应用开发:基于 4.2.2 Jelly Bean 的单位转换实践》 在移动设备上,单元转换是一个常见的需求,无论是日常生活中的...对于想要学习Android开发或深化单位转换应用设计的人来说,这是一个值得研究的实例。
通过研究这个项目,开发者不仅可以深入理解Kotlin语言,还能学习到Android应用的UI设计、事件处理和数据转换等方面的知识。无论是对初学者还是有经验的开发者,这个项目都提供了宝贵的学习机会,有助于提升Android...
通过研究和实践这个“listView时间轴效果”的示例,开发者可以深入理解ListView的工作原理,以及如何利用其特性来实现复杂的界面效果。同时,这也是提升Android UI设计和优化技能的好机会。在实际应用中,这种时间轴...
在Android开发中,ProgressBar是一个非常常见的UI元素,用于显示任务的进度或状态。"ProgressBar-master....通过研究这个项目,你可以学习到如何扩展Android的基础组件,以及如何通过代码和布局文件实现复杂的UI定制。
【安卓仿小米计算器源码 UI】是一个专门为Android平台设计的计算器应用开发项目,其目标是复制小米手机内置计算器的...通过深入研究这个项目,开发者能够提升自己的Android编程技能,并掌握构建复杂功能应用的方法。
总的来说,"ruler:android项目开发原始码示例-项目"是一个深入学习Android自定义View和图形绘制的好案例,它涵盖了Android开发中的多个重要知识点,包括视图创建、图形绘制、事件处理、测量逻辑以及布局设计等。...
通过对BarChar源码的深入研究,开发者不仅可以学习到柱状图的基本实现,还能掌握如何将图表功能集成到自己的Android应用中,同时理解数据可视化、性能优化和用户体验设计等方面的知识。这个源码是学习和实践Android...
AXVideoTimelineView是一款专为Android平台设计的视频裁剪视图组件,它为开发者提供了一种方便的方式来实现视频编辑中的时间线操作。...通过深入研究和实践,我们可以更好地掌握Android上的视频编辑技术。