Android 关于 px、dp、sp 的那些事
来源:互联网 发布:手机游戏下载java 编辑:程序博客网 时间:2024/05/01 14:12
Android 的碎片化导致市场上有几百种不同尺寸和分辨率的机型,所以有 dp 和 sp 的出现,可以尽可能地保证在大部分机型的显示效果是一致的。
概念
px,pixel,像素,屏幕上的一个物理像素点
dp,device independent pixels,又称 dip,设备独立像素,和像素密度(每英寸的像素点)有关
sp,scaled pixels,缩放像素,用于文字展示
sp 和 dp 类似,但多了一个 缩放比例,这是因为系统允许用户自己定义文字的大小(小,正常,大,超大)。比如,用户设置了极小字体,那么如果使用 sp 作为单位的话,应用的字体会随着用户的设置统一缩小。
如果不希望程序受到用户调整字体的影响,可直接用 dp 来设置文字的大小。
dp 是如何计算出来的?
需要理解像素密度 densityDpi。比如 240*320 分辨率的手机,物理尺寸为 1.5英寸 * 2英寸,则横向每英寸的像素点 = 240 / 1.5 = 160dpi,纵向每英寸的像素点 = 320 / 2 = 160dpi,一般机型的这两个值都相等,所以这个手机的像素密度 densityDpi = 160dpi。
然后,在 160dpi 的机型中,1px = 1dp,所以其他 dpi 的机子可以通过下面的换算公式
px = dp * densityDpi / 160 = dp * densitydp = px / density
density = densityDpi / 160 的可以作为一个系数,在 160dpi,density = 1.0;在 240 dpi,density = 1.5;在 320 dpi,density = 2.0
对应到开发 res 资源有
- ldpi 120dpi,0.75
- mdpi 160dpi,1.0
- hdpi 240dpi,1.5
- xhdpi 320dpi,2.0
所以 1dp,到这几个目录中,换算得到的像素大小为
- ldpi 1 * 0.75 = 0.75px
- mdpi 1 * 1.0 = 1px
- hdpi 1 * 1.5 = 1.5px
- xhdpi 1 * 2.0 = 2.0px
使用
Android 有个 DisplayMetrics 类来计算这些值
我一般使用 Application 的 Context 来计算这些值,包括一些需要 Context,但仅仅去读写一些资源而于具体什么类型的 Context 无关的操作。这样的好处可以避免某些引用到 Context 的场景出现内存泄漏
public class BaseApplication extends Application { private static Application mBaseApplication = null; public BaseApplication() { } @Override public void onCreate() { super.onCreate(); mBaseApplication = this; } public static Context getContext() { return mBaseApplication; }}DisplayMetrics metrics = BaseApplication.getContext().getResources().getDisplayMetrics();
具体的换算有下面的工具方法可以实现
/** * dp转px * * @param dpValue dp值 * @return px值 */public static int dp2px(float dpValue) { final float scale = BaseApplication.getContext().getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f);}/** * px转dp * * @param pxValue px值 * @return dp值 */public static int px2dp(float pxValue) { final float scale = BaseApplication.getContext().getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f);}/** * sp转px * * @param spValue sp值 * @return px值 */public static int sp2px(float spValue) { final float fontScale = BaseApplication.getContext().getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f);}/** * px转sp * * @param pxValue px值 * @return sp值 */public static int px2sp(float pxValue) { final float fontScale = BaseApplication.getContext().getResources().getDisplayMetrics().scaledDensity; return (int) (pxValue / fontScale + 0.5f);}/** * 像素的各种单位换算 * <p>该方法存在于TypedValue</p> * * @param unit 单位 * @param value 像素值 * @return 转换结果 */public static float applyDimension(int unit, float value) { DisplayMetrics metrics = BaseApplication.getContext().getResources().getDisplayMetrics(); switch (unit) { case TypedValue.COMPLEX_UNIT_PX: return value; case TypedValue.COMPLEX_UNIT_DIP: return value * metrics.density; case TypedValue.COMPLEX_UNIT_SP: return value * metrics.scaledDensity; case TypedValue.COMPLEX_UNIT_PT: return value * metrics.xdpi * (1.0f / 72); case TypedValue.COMPLEX_UNIT_IN: return value * metrics.xdpi; case TypedValue.COMPLEX_UNIT_MM: return value * metrics.xdpi * (1.0f / 25.4f); } return 0;}
特殊情况
dp 和 sp 的使用可以满足大部分场景的机型适配,但还是会有极端的情况发生,这时候就需要在代码上采用动态适配的方式来解决适配问题
比如某个控件的大小依赖于其他控件的显示,要保证在极端情况下,其他控件完整显示,则可以提前 measure,然后动态改大小,比如
int measureSpec = MeasureSpec.makeMeasureSpec(-1, MeasureSpec.UNSPECIFIED);view1.measure(measureSpec, measureSpec);view2.measure(measureSpec, measureSpec);textView.setMaxWidth(mTotalWidth - view1.getMeasureWidth() - view2.getMeasureWidth());
平时的开发还会遇到各种各样的机型适配问题,单是 dp 还不够。所以对于 View 的 measure,layout,draw 等流程都需要有一定的了解
- Android 关于 px、dp、sp 的那些事
- 关于px、pt、dp和sp的那些事(笔记)
- android 的dp sp px
- Android的sp,dp,px
- 关于Android布局中px,pt,dp,sp的总结
- Android开发基础知识-关于px,dp,dip,sp的不同之处
- 关于Android setTextSize() 以及 px dip/dp sp的说明
- 关于dp、px、sp的理解
- android dp,sp,px
- Android的px、dp、sp的区别
- android dp dip px sp的区别
- (转)android px dp sp 的区别
- dp、sp和px的区别【Android】
- Android的px、dp和sp
- android dp dip px sp的区别
- android 中sp、dp、px的详解
- Android px, dp, sp的区别
- dp,px,sp android间的转换
- POJ1979——Red and Black
- tr td colSpan(列) rowSpan(行)合并
- JavaScript----01_内存分配
- 9.1AT课堂M笔记
- 【STL】deque的常用方法
- Android 关于 px、dp、sp 的那些事
- [GDOI2017模拟9.4]同桌的你
- Arithmetic Progression
- Codeforces 588 C Duff and Weight Lifting【思维】
- HTTP协议知识点
- bzoj1179(缩点+乱搞)
- Android资源文件(备忘录) 供个人记忆
- 关于一些常识的总结
- leetcode题解