将像素转换为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上的ldpi120 dpi)
  • 1.0 mdpi160 dpi;基准)
  • 1.5hdpi240 dpi)
  • 2.0 xhdpi320 dpi)
  • 3.0 xxhdpi480 dpi)
  • 4.0xxxhdpi640 dpi)

使用此在线转换器可以播放dpi值。

编辑:这似乎有没有1:1的关系,桶和density 。 看起来像xxhdpiNexus 5Xdensity值是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 

上面有很多很棒的解决scheme。 但是,我发现最好的解决scheme是谷歌的devise:

https://design.google.com/devices/

密度

PXDP是不同的但相似。

当您仅考虑屏幕的物理尺寸时, 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); }