1、DisplayMetrics
/**
* A structure describing general information about a display, such as its
* size, density, and font scaling.
* <p>To access the DisplayMetrics members, initialize an object like this:</p>
* <pre> DisplayMetrics metrics = new DisplayMetrics();
* getWindowManager().getDefaultDisplay().getMetrics(metrics);</pre>
*/
源码解释:设备显示的基本信息:大小、密度、以及字体缩放;通过我们通过以下代码获取相关类的实例:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
另外:在Resources类中也可以通过以下方法获取实例:
public DisplayMetrics getDisplayMetrics() {
if (DEBUG_CONFIG) Slog.v(TAG, "Returning DisplayMetrics: " + mMetrics.widthPixels
+ "x" + mMetrics.heightPixels + " " + mMetrics.density);
return mMetrics;
}
该类平时主要用来获取设备的分辨率:通过widthPixels和heightPixels属性,这两个属性都是public类型的,可以直接获取。
2、TypedValue
/**
* Container for a dynamically typed data value. Primarily used with
* {@link android.content.res.Resources} for holding resource values.
*/
动态数据的容器,主要是配合Resources类进行使用;平时,我们在使用自定义属性的时候,通过需要给某个自定义属性一个默认值,我们会用到TypedValue,例如:
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 58, getResources().getDisplayMetrics());
该方法的主要实现如下:
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;
}
通常我们主要会用到,COMPLEX_UNIT_DIP单位是dip;
3、getDimension getDimensionPixelOffset getDimensionPixelSize
这3个Resouces的区别,都是用来获取dimen值的;以下是他们的相关源码:
getDimension:
public float getDimension(int id) throws NotFoundException {
/// M: Log specified resource Id @{
if(DEBUG_RESOURCE_ID && (id == sLogId)) {
Slog.i(TAG, "**** getDimension id:" + id);
Slog.i(TAG, "config is " + mConfiguration);
}
/// @}
synchronized (mAccessLock) {
TypedValue value = mTmpValue;
if (value == null) {
mTmpValue = value = new TypedValue();
}
getValue(id, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimension(value.data, mMetrics);
}
throw new NotFoundException(
"Resource ID #0x" + Integer.toHexString(id) + " type #0x"
+ Integer.toHexString(value.type) + " is not valid");
}
}
getDimensionPixelOffset:
public int getDimensionPixelOffset(int id) throws NotFoundException {
/// M: Log specified resource Id @{
if(DEBUG_RESOURCE_ID && (id == sLogId)) {
Slog.i(TAG, "**** getDimensionPixelOffset id:" + id);
Slog.i(TAG, "config is " + mConfiguration);
}
/// @}
synchronized (mAccessLock) {
TypedValue value = mTmpValue;
if (value == null) {
mTmpValue = value = new TypedValue();
}
getValue(id, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelOffset(
value.data, mMetrics);
}
throw new NotFoundException(
"Resource ID #0x" + Integer.toHexString(id) + " type #0x"
+ Integer.toHexString(value.type) + " is not valid");
}
}
getDimensionPixelSize:
public int getDimensionPixelSize(int id) throws NotFoundException {
/// M: Log specified resource Id @{
if(DEBUG_RESOURCE_ID && (id == sLogId)) {
Slog.i(TAG, "**** getDimensionPixelSize id:" + id);
Slog.i(TAG, "config is " + mConfiguration);
}
/// @}
synchronized (mAccessLock) {
TypedValue value = mTmpValue;
if (value == null) {
mTmpValue = value = new TypedValue();
}
getValue(id, value, true);
if (value.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelSize(
value.data, mMetrics);
}
throw new NotFoundException(
"Resource ID #0x" + Integer.toHexString(id) + " type #0x"
+ Integer.toHexString(value.type) + " is not valid");
}
}
可以看到他们的主要区别就是调用TypedValue的相应方法的不同而已,其他都是一样的;
下面我们主要看TypedValue的complexToDimension方法:
public static float complexToDimension(int data, DisplayMetrics metrics)
{
return applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
complexToFloat(data),
metrics);
}
可以看到就是调用applyDimension接口获取相应的值;complexToDimensionPixelOffset方法如下:
public static int complexToDimensionPixelOffset(int data,
DisplayMetrics metrics)
{
return (int)applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
complexToFloat(data),
metrics);
}
就是将complexToDimension的值强制转化为int类型,也就是取整部分;complexToDimensionPixelSize方法:
public static int complexToDimensionPixelSize(int data,
DisplayMetrics metrics)
{
final float value = complexToFloat(data);
final float f = applyDimension(
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
value,
metrics);
final int res = (int)(f+0.5f);
if (res != 0) return res;
if (value == 0) return 0;
if (value > 0) return 1;
return -1;
}
就是将complexToDimension的值加上0.5再强制转化为int,也就是我们通常说的四舍五入。。。好了,得好好上班了