将像素转换为dp

时间:2011-01-05 15:04:28

标签: android pixel resolution dpi

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

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

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

35 个答案:

答案 0 :(得分:965)

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

答案 1 :(得分:804)

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

答案 2 :(得分:275)

最好放入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;
}

答案 3 :(得分:186)

float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;

density等于

  • .75ldpi120 dpi)
  • 上 {li> 1.0 mdpi160 dpi;基线)
  • 1.5hdpi240 dpi)
  • 2.0xhdpi320 dpi)
  • 3.0xxhdpi480 dpi)
  • 4.0xxxhdpi640 dpi)

使用此online converter来播放dpi值。

编辑: 似乎dpi桶和density之间没有1:1的关系。看起来Nexus 5X xxhdpi的{​​{1}}值为density(而不是2.625)。请参阅Device Metrics

答案 4 :(得分:88)

如果您可以使用维度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);

答案 5 :(得分:77)

根据Android开发指南:

px = dp * (dpi / 160)

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

dp = px / (dpi / 160)

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

答案 6 :(得分:73)

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

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来做到这一点。

答案 7 :(得分:67)

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

答案 8 :(得分:40)

适用于DP to Pixel

dimens.xml

中创建一个值
<dimen name="textSize">20dp</dimen>

pixel中获取该值为:

int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);

答案 9 :(得分:38)

因此,您可以使用以下配方设计器从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);
}

答案 10 :(得分:34)

对于任何使用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

答案 11 :(得分:33)

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

float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())

答案 12 :(得分: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);
}

答案 13 :(得分:15)

科特林

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

Java

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

答案 14 :(得分:12)

如果你在维度里面得到维度,最好的方法是直接从getDimension()方法获取维度,它会返回已经转换为像素值的维度。

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

为了更好地解释这一点,

getDimension(int resourceId) 

将返回已转换为像素AS A FLOAT的维度。

getDimensionPixelSize(int resourceId)

将返回相同但截断为int,因此AS AN INTEGER。

请参阅Android reference

答案 15 :(得分:10)

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

更新:

由于displayMetricsglobal shared Resources的一部分,我们可以使用Resources.getSystem()

fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()

fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()

答案 16 :(得分:9)

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

其中resource是context.getResources()。

答案 17 :(得分: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;
    }
}

依赖于Context,返回浮点值,静态方法

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

答案 18 :(得分: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;
    }
}

答案 19 :(得分:7)

使用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}")

答案 20 :(得分:6)

这就是我的工作方式:

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

你可以对宽度做同样的事。

答案 21 :(得分:6)

float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);

答案 22 :(得分:6)

将像素转换为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());

希望能帮助。

答案 23 :(得分:5)

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

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

Density

答案 24 :(得分:5)

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

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

答案 25 :(得分:4)

PXDP不同但相似。

当您仅考虑屏幕的物理尺寸时,

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

有时你实际上想要pixels,当你处理代码中的维度时,你总是处理真实的pixels,除非你转换它们。

所以在Android设备上,正常大小的hdpi屏幕,800x480 is 533x320 DP(我相信)。要将DP转换为pixels /1.5,请转换回*1.5。这仅适用于一个屏幕尺寸和dpi,它会根据设计而改变。我们的艺术家会给我pixels,但我会使用上述DP等式转换为1.5

答案 26 :(得分:2)

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

public static int pxFromDp(final float dp) {
        return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
    }

答案 27 :(得分:2)

这适用于我(C#):

int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);

答案 28 :(得分:2)

private fun toDP(context: Context,value: Int): Int {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
        value.toFloat(),context.resources.displayMetrics).toInt()
}

答案 29 :(得分:1)

科特林

buildscript {

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.4'


        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

java

   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
}

答案 30 :(得分:0)

对于Xamarin.Android

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

制作自定义渲染器时,必须使它为非静态

答案 31 :(得分:0)

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

答案 32 :(得分:-2)

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


                        }
                    });
                }
            });

答案 33 :(得分:-2)

要转换dp to px,此代码可能会有所帮助:

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

答案 34 :(得分:-3)

对于React Native Java代码,已经有一个util类:

import com.facebook.react.uimanager.PixelUtil;

float dp = PixelUtil.toDIPFromPixel(somePixelValue);