一、px与dp/sp区别:
px:像素单位
dp/sp:像素无关单位
View 的尺寸和距离,使用 dp 为单位。
字体的大小,使用 sp 为单位。
不同分辨率单位转换:
ldpi 240*320 1dp=0.75px
mdpi 320*480 1dp=1px
hdpi 480*800 1dp=1.5px
xhdpi 720*1280 1dp=2px
xxhdpi 1080*1920 1dp=3px
Android studio中的xml布局中–>preview—>可以选择不同分辨率
示例:
720*1280,分别单位:25dp / 25sp / 50px , 效果完全相同,
1、调整屏幕为:1080*1920,发现25dp / 25sp 完全相同,但是50px效果貌似缩小了,如下图:
但是把px值调为75px (1dp=3px),又发现和25dp、25sp效果相同,如下图:
2、调整屏幕为:480*800 ,发现25dp / 25sp 完全相同,但是50px效果貌似变大了,如下图:
但是把px值调为37.5px (1dp=1.5px),又发现和25dp、25sp效果相同,如下图:
二、sp/dp的区别:
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="安卓开发工程师"
android:textSize="25sp" />
<TextView
android:layout_width="25sp"
android:layout_height="25sp"
android:background="#0000ff" />
<TextView
android:id="@+id/tv2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="安卓开发工程师"
android:textSize="25dp" />
<TextView
android:layout_width="25dp"
android:layout_height="25dp"
android:background="#ff0000" />
</LinearLayout>
华为手机系统字体设置:
设置标准(系统默认)时,发现25dp/25sp效果相同。
调整字体为大时:
发现sp与dp效果出现了不同,sp不仅随分辨率不同而改变,而且还随系统字体设置而改变,而dp只随分辨率不同而改变。
使用 sp 为单位标记字体,会随着系统的字体大小而改变。而使用 dp 则不会。
三、探索sp/dp源码:
使用 sp 为单位标记字体,会随着系统的字体大小而改变。而使用 dp 则不会。
推荐使用 sp 来作为字体单位,但是如果有需要字体尺寸不跟随系统字体尺寸变动,则可以使用 dp 来作为字体单位。
setTextSize方法
public void setTextSize(int unit, float size) {
Context c = getContext();
Resources r;
if (c == null)
r = Resources.getSystem();
else
r = c.getResources();
setRawTextSize(TypedValue.applyDimension(
unit, size, r.getDisplayMetrics()));
}
applyDimension方法:
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;
}
density、scaledDensity
/**
* The logical density of the display. This is a scaling factor for the
* Density Independent Pixel unit, where one DIP is one pixel on an
* approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen),
* providing the baseline of the system's display. Thus on a 160dpi screen
* this density value will be 1; on a 120 dpi screen it would be .75; etc.
*
* <p>This value does not exactly follow the real screen size (as given by
* {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of
* the overall UI in steps based on gross changes in the display dpi. For
* example, a 240x320 screen will have a density of 1 even if its width is
* 1.8", 1.3", etc. However, if the screen resolution is increased to
* 320x480 but the screen size remained 1.5"x2" then the density would be
* increased (probably to 1.5).
* 屏幕密度
* @see #DENSITY_DEFAULT
*/
public float density;
/**
* A scaling factor for fonts displayed on the display. This is the same
* as {@link #density}, except that it may be adjusted in smaller
* increments at runtime based on a user preference for the font size.
* 类似density(屏幕密度),但是还会随着系统用户的选择而改变。
*/
public float scaledDensity;