将像素转换为dp
我已经创build了我的应用程序,其高分辨率为480×800,Pantech设备的像素为高。
我需要为G1设备转换高度和宽度。 我认为把它转换成DP将解决这个问题,并为两个设备提供相同的解决scheme。
有没有简单的方法将像素转换为DP? 有什么build议么?
/// Converts 14 dip into its equivalent px Resources r = getResources(); float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, r.getDisplayMetrics());
/** * This method converts dp unit to equivalent pixels, depending on device density. * * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels * @param context Context to get resources and device specific display metrics * @return A float value to represent px equivalent to dp depending on device density */ public static float convertDpToPixel(float dp, Context context){ Resources resources = context.getResources(); DisplayMetrics metrics = resources.getDisplayMetrics(); float px = dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT); return px; } /** * This method converts device specific pixels to density independent pixels. * * @param px A value in px (pixels) unit. Which we need to convert into db * @param context Context to get resources and device specific display metrics * @return A float value to represent dp equivalent to px value */ public static float convertPixelsToDp(float px, Context context){ Resources resources = context.getResources(); DisplayMetrics metrics = resources.getDisplayMetrics(); float dp = px / ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT); return dp; }
最好放在一个Util.java类中
public static float dpFromPx(final Context context, final float px) { return px / context.getResources().getDisplayMetrics().density; } public static float pxFromDp(final Context context, final float dp) { return dp * context.getResources().getDisplayMetrics().density; }
float density = context.getResources().getDisplayMetrics().density; float px = someDpValue * density; float dp = somePxValue / density;
density
相等
- 在
ldpi
上的ldpi
(120
dpi) -
1.0
mdpi
(160
dpi;基准) -
1.5
在hdpi
(240
dpi) -
2.0
xhdpi
(320
dpi) -
3.0
xxhdpi
(480
dpi) -
4.0
上xxxhdpi
(640
dpi)
使用此在线转换器可以播放dpi值。
编辑:这似乎有没有1:1的关系,桶和density
。 看起来像xxhdpi
的Nexus 5X
的density
值是2.625
(而不是3
)。 请参阅设备度量标准 。
根据Android开发指南:
px = dp * (dpi / 160)
但是,当你收到一个以像素表示的devise时,通常你会希望这样做。 所以:
dp = px / (dpi / 160)
如果你使用的是240dpi设备,那么这个比率是1.5(如前所述),所以这意味着在应用程序中60px图标等于40dp。
没有Context
,优雅的静态方法:
public static int dpToPx(int dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } public static int pxToDp(int px) { return (int) (px / Resources.getSystem().getDisplayMetrics().density); }
如果你可以使用尺寸XML,这是非常简单的!
在你的res/values/dimens.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="thumbnail_height">120dp</dimen> ... ... </resources>
然后在你的Java:
getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
你可以使用这个.. 没有上下文
public static int pxToDp(int px) { return (int) (px / Resources.getSystem().getDisplayMetrics().density); } public static int dpToPx(int dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); }
因此,您可以使用以下公式计算dp中指定尺寸的像素数量
public int convertToPx(int dp) { // Get the screen's density scale final float scale = getResources().getDisplayMetrics().density; // Convert the dps to pixels, based on density scale return (int) (dp * scale + 0.5f); }
对于DP to Pixel
在dimens.xml
创build一个值
<dimen name="textSize">20dp</dimen>
以pixel
为单位获取该值:
int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);
在android SDK中有一个默认的util: http : //developer.android.com/reference/android/util/TypedValue.html
float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
可能最好的方法是,如果维度值在values / dimen中,则直接从getDimension()方法获取维度,它会返回已经转换为像素值的维度。
context.getResources().getDimension(R.dimen.my_dimension)
为了更好地解释这一点,
getDimension(int resourceId)
将返回已经转换为像素AS FLOAT的尺寸。
getDimensionPixelSize(int resourceId)
将返回相同但截断为int,所以AS AN INTEGER。
请参阅Android参考
将dp转换为像素。
public static int dp2px(Resources resource, int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,resource.getDisplayMetrics()); }
将像素转换为dp。
public static float px2dp(Resources resource, float px) { return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics()); }
其中资源是context.getResources()。
喜欢这个:
public class ScreenUtils { public static float dpToPx(Context context, float dp) { if (context == null) { return -1; } return dp * context.getResources().getDisplayMetrics().density; } public static float pxToDp(Context context, float px) { if (context == null) { return -1; } return px / context.getResources().getDisplayMetrics().density; } }
依赖于Context,返回浮点值,静态方法
来自: https : //github.com/Trinea/android-common/blob/master/src/cn/trinea/android/common/util/ScreenUtils.java#L15
如果你开发一个性能关键的应用程序,请考虑下面的优化类:
public final class DimensionUtils { private static boolean isInitialised = false; private static float pixelsPerOneDp; // Suppress default constructor for noninstantiability. private DimensionUtils() { throw new AssertionError(); } private static void initialise(View view) { pixelsPerOneDp = view.getResources().getDisplayMetrics().densityDpi / 160f; isInitialised = true; } public static float pxToDp(View view, float px) { if (!isInitialised) { initialise(view); } return px / pixelsPerOneDp; } public static float dpToPx(View view, float dp) { if (!isInitialised) { initialise(view); } return dp * pixelsPerOneDp; } }
你应该像使用像素一样使用dp。 他们就是这样。 显示独立的像素。 在中等密度的屏幕上使用相同的数字,在高密度的屏幕上,尺寸将是魔术般正确的。
但是,这听起来像你所需要的是在你的布局devisefill_parent选项。 当您希望您的视图或控件展开为父容器中的所有剩余大小时,请使用fill_parent。
将像素转换为dp使用TypedValue 。
正如提到的文档:容器为dynamictypes的数据值。
并使用applyDimension方法:
public static float applyDimension (int unit, float value, DisplayMetrics metrics)
它将保持一个维度的解压后的复杂数据值转换为其最终的浮点值,如下所示:
Resources resource = getResources(); float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics());
希望有所帮助。
float scaleValue = getContext().getResources().getDisplayMetrics().density; int pixels = (int) (dps * scaleValue + 0.5f);
这是对我来说是如何工作的:
DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); int h = displaymetrics.heightPixels; float d = displaymetrics.density; int heightInPixels=(int) (h/d);
你可以做同样的宽度。
对于任何使用Kotlin的人:
val Int.toPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt() val Int.toDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt()
用法:
64.toPx 32.toDp
PX
和DP
是不同的但相似。
当您仅考虑屏幕的物理尺寸时, DP
是分辨率。 当您使用DP
它会将您的布局缩放到具有不同pixel
密度的其他类似尺寸的屏幕。
有时你实际上需要pixels
,而当你处理代码中的维度时,你总是处理真实的pixels
,除非你转换它们。
所以在Android设备上,正常大小的hdpi
屏幕, 800x480 is 533x320
DP
800x480 is 533x320
(我相信)。 将DP
转换为pixels /1.5
,转换回*1.5
。 这只是一个屏幕大小和dpi
,它会根据devise而改变。 我们的艺术家给我的pixels
但我转换到DP
与上述1.5
方程。
使用kotlin的扩展function更优雅的方法
/** * Converts dp to pixel */ val Int.dpToPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt() /** * Converts pixel to dp */ val Int.pxToDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt()
用法:
println("16 dp in pixel: ${16.dpToPx}") println("16 px in dp: ${16.pxToDp}")
这为我工作(C#):
int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);
要将dp to px
转换dp to px
此代码可能会有帮助:
public static int dpToPx(Context context, int dp) { int px = Math.round(dp * getPixelScaleFactor(context)); return px; } private static float getPixelScaleFactor(Context context) { DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); return (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT); }