我已经为分辨率为480x800的Pantech设备创建了以像素为单位的高度和宽度的应用程序。

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

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


当前回答

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

在某些情况下,您需要用dp表示尺寸,然后 把它们转换成像素。dp单位到屏幕像素的转换是 简单: Px = 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() }

其他回答

根据Android开发指南:

px = dp * (dpi / 160)

但通常当你收到以像素表示的设计时,你会希望以另一种方式执行这个操作。所以:

dp = px / (dpi / 160)

如果你在一个240dpi的设备上,这个比例是1.5(如前所述),所以这意味着一个60px的图标在应用程序中等于40dp。

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

在某些情况下,您需要用dp表示尺寸,然后 把它们转换成像素。dp单位到屏幕像素的转换是 简单: Px = 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() }

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

最好的答案来自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)

要将dp转换为px,这段代码可能很有用:

public static int dpToPx(Context context, int dp) {
       final float scale = context.getResources().getDisplayMetrics().density;
       return (int) (dp * scale + 0.5f);
    }