918

我已经创建了我的应用程序,其高度和宽度以像素为单位为分辨率为480x800.

我需要为 G1 设备转换高度和宽度。
我认为将其转换为 dp 将解决问题并为两种设备提供相同的解决方案。

有什么简单的方法可以将像素转换为 dp?
有什么建议么?

4

35 回答 35

1133

Java代码:

// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP,
    dip,
    r.getDisplayMetrics()
);

科特林代码:

 val dip = 14f
 val r: Resources = resources
 val px = TypedValue.applyDimension(
     TypedValue.COMPLEX_UNIT_DIP,
     dip,
     r.displayMetrics
 )

Kotlin 扩展:

val Number.toPx get() = TypedValue.applyDimension(
  TypedValue.COMPLEX_UNIT_DIP,
  this.toFloat(),
  Resources.getSystem().displayMetrics)
于 2011-06-13T05:56:57.797 回答
921
/**
 * 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){
    return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

/**
 * 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){
    return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
于 2012-03-05T08:09:39.393 回答
306

最好放入 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;
}
于 2012-08-27T18:34:02.410 回答
213
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;

density等于

  • .75ldpi( 120dpi)
  • 1.0mdpi160dpi;基线)
  • 1.5hdpi( 240dpi)
  • 2.0xhdpi( 320dpi)
  • 3.0xxhdpi( 480dpi)
  • 4.0xxxhdpi( 640dpi)

使用这个在线转换器来玩转 dpi 值。

编辑:dpibucket 和density. 看起来该Nexus 5X存在xxhdpidensity值是2.625(而不是3)。在Device Metrics中亲自查看。

于 2012-02-14T09:56:14.247 回答
137

你可以使用这个 ..没有上下文

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);
}

正如@Stan 提到的......如果系统改变密度,使用这种方法可能会导致问题。所以要注意这一点!

就我个人而言,我正在使用 Context 来做到这一点。这只是我想与您分享的另一种方法

于 2016-08-09T03:42:47.480 回答
104

如果您可以使用尺寸 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);
于 2013-10-16T01:39:53.677 回答
75

根据Android开发指南:

px = dp * (dpi / 160)

但是,当您收到以像素为单位的设计时,您通常会希望以相反的方式执行此操作。所以:

dp = px / (dpi / 160)

如果您使用的是 240dpi 设备,则此比率为 1.5(如前所述),因此这意味着 60px 图标在应用程序中等于 40dp。

于 2011-12-05T19:00:36.480 回答
72

Without Context, elegant static methods:

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);
}
于 2013-07-26T11:20:35.993 回答
47

为了DP to Pixel

创造价值dimens.xml

<dimen name="textSize">20dp</dimen>

获取该值pixel

int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);
于 2015-12-11T10:22:31.040 回答
47

对于使用 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
于 2017-08-25T17:04:06.053 回答
46

使用 kotlin-extension 让它变得更好

fun Int.toPx(context: Context): Int = (this * context.resources.displayMetrics.density).toInt()

fun Int.toDp(context: Context): Int = (this / context.resources.displayMetrics.density).toInt()

更新:

因为displayMetrics全局共享资源的一部分,我们可以使用Resources.getSystem()

val Float.toPx get() = this * Resources.getSystem().displayMetrics.density
val Float.toDp get() = this / Resources.getSystem().displayMetrics.density

val Int.toPx get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp get() = (this / Resources.getSystem().displayMetrics.density).toInt()
于 2019-03-03T12:04:26.617 回答
41

因此,您可以使用以下公式从 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);
}
于 2012-03-28T09:39:12.073 回答
35

android SDK中有一个默认的util:http: //developer.android.com/reference/android/util/TypedValue.html

float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
于 2014-02-12T15:53:40.110 回答
24

科特林

fun convertDpToPixel(dp: Float, context: Context): Float {
    return dp * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}

fun convertPixelsToDp(px: Float, context: Context): Float {
    return px / (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}

爪哇

public static float convertDpToPixel(float dp, Context context) {
    return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

public static float convertPixelsToDp(float px, Context context) {
    return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
于 2018-09-21T13:35:21.670 回答
19

这应该给你转换 dp 到像素:

public static int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

这应该为您提供到 dp 的转换像素:

public static int pxToDp(int px)
{
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
于 2018-05-02T06:02:02.900 回答
13

如果您在 values/dimen 中有维度,最好的方法可能是直接从 getDimension() 方法获取维度,它将返回已经转换为像素值的维度。

context.getResources().getDimension(R.dimen.my_dimension)

只是为了更好地解释这一点,

getDimension(int resourceId) 

将返回已转换为像素的尺寸作为 FLOAT。

getDimensionPixelSize(int resourceId)

将返回相同但截断为 int,因此作为整数。

请参阅Android 参考

于 2014-10-31T14:37:52.997 回答
8

像这样:

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;
    }
}

依赖于上下文,返回浮点值,静态方法

来自:https ://github.com/Trinea/android-common/blob/master/src/cn/trinea/android/common/util/ScreenUtils.java#L15

于 2014-02-14T08:43:56.243 回答
8

使用 kotlin 的扩展函数更优雅的方法

/**
 * 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}")
于 2017-08-10T13:46:45.123 回答
7

如果您开发性能关键应用程序,请考虑以下优化类:

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;
    }
}
于 2013-03-19T09:19:27.463 回答
7
float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);
于 2015-04-22T06:45:17.677 回答
7

将像素转换为 dp 使用TypedValue

如文档所述:动态类型数据值的容器。

并使用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());

希望有帮助。

于 2014-02-03T07:32:31.917 回答
6

这对我来说是这样的:

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int  h = displaymetrics.heightPixels;
float  d = displaymetrics.density;
int heightInPixels=(int) (h/d);

您可以对宽度执行相同的操作。

于 2013-07-02T14:20:25.770 回答
6

将 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()。

于 2016-05-13T11:06:06.827 回答
5

上面有很多很棒的解决方案。但是,我找到的最佳解决方案是谷歌的设计:

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

密度

于 2016-07-21T20:39:14.170 回答
4

PX并且DP不同但相似。

DP是仅考虑屏幕物理尺寸时的分辨率。当您使用它时,它将您的布局缩放到具有不同密度DP的其他类似大小的屏幕。pixel

有时你确实想要pixels,当你在代码中处理维度时,你总是在处理 real pixels,除非你转换它们。

所以在安卓设备上,正常大小的hdpi屏幕,800x480 is 533x320DP(我相信)。转换DPpixels /1.5,转换回来*1.5。这仅适用于一种屏幕尺寸dpi,并且会根据设计而改变。我们的艺术家给了我,我用上面的等式pixels转换成。DP1.5

于 2011-08-25T04:36:43.180 回答
4

您应该像使用像素一样使用 dp 。他们就是这样;显示独立像素。在中等密度屏幕上使用相同的数字,在高密度屏幕上大小会神奇地正确。

但是,听起来您需要的是布局设计中的 fill_parent 选项。当您希望视图或控件扩展到父容器中的所有剩余大小时,请使用 fill_parent。

于 2011-01-05T15:09:47.303 回答
4
private fun toDP(context: Context,value: Int): Int {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
        value.toFloat(),context.resources.displayMetrics).toInt()
}
于 2019-10-07T14:13:16.540 回答
3

科特林

   fun spToPx(ctx: Context, sp: Float): Float {
    return sp * ctx.resources.displayMetrics.scaledDensity
}

fun pxToDp(context: Context, px: Float): Float {
    return px / context.resources.displayMetrics.density
}

fun dpToPx(context: Context, dp: Float): Float {
    return dp * context.resources.displayMetrics.density
}

爪哇

   public static float spToPx(Context ctx,float sp){
    return sp * ctx.getResources().getDisplayMetrics().scaledDensity;
}

public static float pxToDp(final Context context, final float px) {
    return px / context.getResources().getDisplayMetrics().density;
}

public static float dpToPx(final Context context, final float dp) {
    return dp * context.getResources().getDisplayMetrics().density;
}
于 2018-10-04T09:28:16.187 回答
3

最好的答案来自 Android 框架本身:只需使用这个相等性...

public static int dpToPixels(final DisplayMetrics display_metrics, final float dps) {
    final float scale = display_metrics.density;
    return (int) (dps * scale + 0.5f);
}

(将 dp 转换为 px)

于 2019-08-08T09:01:38.710 回答
3

如果你想要数值,那么使用 Math.round() 会将浮点数四舍五入到最接近的整数。

public static int pxFromDp(final float dp) {
        return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
    }
于 2018-04-24T02:38:33.180 回答
2

这对我有用(C#):

int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);
于 2016-08-07T05:16:17.753 回答
1

对于 Xamarin.Android

float DpToPixel(float dp)
{
    var resources = Context.Resources;
    var metrics = resources.DisplayMetrics;
    return dp * ((float)metrics.DensityDpi / (int)DisplayMetricsDensity.Default);
}

当您制作自定义渲染器时,必须将其设为非静态

于 2018-09-20T10:23:26.773 回答
0

开发人员文档提供了有关如何将 dp 单位转换为像素单位的答案:

在某些情况下,您需要以 dp 表示尺寸,然后将它们转换为像素。dp 单位到屏幕像素的转换很简单:

像素 = dp * (dpi / 160)

提供了两个代码示例,一个 Java 示例和一个 Kotlin 示例。这是 Java 示例:

// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels...

Kotlin 示例:

// The gesture threshold expressed in dp
private const val GESTURE_THRESHOLD_DP = 16.0f
...
private var mGestureThreshold: Int = 0
...
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // Get the screen's density scale
    val scale: Float = resources.displayMetrics.density
    // Convert the dps to pixels, based on density scale
    mGestureThreshold = (GESTURE_THRESHOLD_DP * scale + 0.5f).toInt()

    // Use mGestureThreshold as a distance in pixels...
}

我从 Java 示例创建的 Java 方法运行良好:

/**
 * Convert dp units to pixel units
 * https://developer.android.com/training/multiscreen/screendensities#dips-pels
 *
 * @param dip input size in density independent pixels
 *            https://developer.android.com/training/multiscreen/screendensities#TaskUseDP
 *
 * @return pixels
 */
private int dpToPixels(final float dip) {
    // Get the screen's density scale
    final float scale = this.getResources().getDisplayMetrics().density;
    // Convert the dps to pixels, based on density scale
    final int pix = Math.round(dip * scale + 0.5f);
    
    if (BuildConfig.DEBUG) {
        Log.i(DrawingView.TAG, MessageFormat.format(
                "Converted: {0} dip to {1} pixels",
                dip, pix));
    }
    
    return pix;
}

此问题的其他几个答案提供了与此答案类似的代码,但其他答案中没有足够的支持文档让我知道其他答案之一是否正确。接受的答案也与此答案不同。我认为开发人员文档清楚地说明了 Java 解决方案。

Compose 中也有一个解决方案。Compose 中的密度为与设备无关的像素 (dp) 和像素之间的转换提供了一种单行解决方案。

val sizeInPx = with(LocalDensity.current) { 16.dp.toPx() }
于 2021-11-04T20:46:32.927 回答
-2

To convert dp to px this code can be helpful :

public static int dpToPx(Context context, int dp) {
       final float scale = context.getResources().getDisplayMetrics().density;
       return (int) (dp * scale + 0.5f);
    }
于 2016-01-06T09:05:20.550 回答
-3
((MyviewHolder) holder).videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(final MediaPlayer mediaPlayer) {
        mediaPlayer.setLooping(true);
        ((MyviewHolder) holder).spinnerView.setVisibility(View.GONE);
        mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
           @Override
           public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
               /*
               * add media controller
               */
               MediaController controller = new MediaController(mContext);
               float density = mContext.getResources().getDisplayMetrics().density;
               float px = 55 * density;
               // float dp = somePxValue / density;
               controller.setPadding(0, 0, 0, (int) (px));
               ((MyviewHolder) holder).videoView.setMediaController(controller);
            }
        });
    }
});
于 2018-09-10T17:54:07.567 回答