web-dev-qa-db-ja.com

式pxからdp、dpからpx android

私は、密度に依存しないピクセルからピクセルへの可変量を計算しようとしています。

この式(px to dp): dp = (int)(px / (displayMetrics.densityDpi / 160));は、ゼロで除算されるため、小さなデバイスでは機能しません。

これは私のdpからpxへの公式です:

px = (int)(dp * (displayMetrics.densityDpi / 160));

誰かが私にいくつかのポインタを与えることができますか?

143
Bram

注:上記で広く使用されているソリューションは、displayMetrics.densityに基づいています。ただし、ドキュメントでは、この値は画面の「バケット」で使用される丸められた値であると説明しています。例えば。 Nexus 10では2が返されます。実際の値は298dpi(実)/ 160dpi(デフォルト)= 1.8625です。

要件に応じて、次のように実現できる正確な変換が必要になる場合があります。

[編集]これはもちろんスクリーンバケットに基づいているため、これはAndroidの内部dpユニットと混合することを意図したものではありません。異なるデバイスで同じ実サイズをレンダリングするユニットが必要な場合に使用します。

Dpをピクセルに変換します。

public int dpToPx(int dp) {
    DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
    return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));     
}

ピクセルをdpに変換します。

public int pxToDp(int px) {
    DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
    return Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}

Xdpiとydpiのプロパティがあることに注意してください。区別したいかもしれませんが、これらの値が大きく異なる正気なディスプレイは想像できません。

309
Bachi

次の式を使用して問題を解決しました。他の人々がそれから利益を得るように。

dpからpx:

displayMetrics = context.getResources().getDisplayMetrics();
return (int)((dp * displayMetrics.density) + 0.5);

pxからdp:

displayMetrics = context.getResources().getDisplayMetrics();
return (int) ((px/displayMetrics.density)+0.5);
101
Bram

pxからdp:

int valueInpx = ...;
int valueInDp= (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, valueInpx , getResources()
                .getDisplayMetrics());
32
Kannan Suresh

getResources().getDimensionPixelSize(R.dimen.your_dimension)を呼び出して、dp単位からピクセルに変換するだけです

27
pelotasplus

効率的な方法

DP to Pixel:

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

DPのピクセル:

private int pxToDp(int px)
{
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}

これがお役に立てば幸いです。

27
Hiren Patel

この関数を使用

private int dp2px(int dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
px = dp * (dpi / 160)

dp = px * (160 / dpi)
5
ct_rob

ほとんどの場合、変換関数は頻繁に呼び出されます。メモ化を追加することで最適化できます。そのため、関数が呼び出されるたびに計算されるわけではありません。

計算された値を保存するHashMapを宣言しましょう。

private static Map<Float, Float> pxCache = new HashMap<>();

ピクセル値を計算する関数:

public static float calculateDpToPixel(float dp, Context context) {

        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float px = dp * (metrics.densityDpi / 160f);
        return px;

    }

HashMapから値を返し、以前の値の記録を保持するメモ化関数。

Javaでは、メモ化をさまざまな方法で実装できます。 Java 7の場合

public static float convertDpToPixel(float dp, final Context context) {

        Float f = pxCache.get(dp);
        if (f == null) {
            synchronized (pxCache) {
                f = calculateDpToPixel(dp, context);
                pxCache.put(dp, f);
            }

        }

        return f;
    }

Java 8はLambda関数をサポート

public static float convertDpToPixel(float dp, final Context context) {

        pxCache.computeIfAbsent(dp, y ->calculateDpToPixel(dp,context));
}

ありがとう。

3
Parth mehta

以下の機能は、デバイス間でうまく機能しました。

https://Gist.github.com/laaptu/7867851 から取得されます

public static float convertPixelsToDp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}

public static float convertDpToPixel(float dp){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float px = dp * (metrics.densityDpi / 160f);
    return Math.round(px);
}
2
Blesson Jose
2
KMI

[DisplayMatrics][1]を使用して、画面密度を決定できます。このようなもの:

int pixelsValue = 5; // margin in pixels
float d = context.getResources().getDisplayMetrics().density;
int margin = (int)(pixelsValue * d);

私が覚えているように、オフセットにはフローリングを使用し、幅には丸めを使用する方が良いです。

1
Houcine

// Decimal/Floatで取得するため

public static float convertPixelsToDp(float px, Context context) {

    Resources resources = context.getResources();
    DisplayMetrics metrics = resources.getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}



public static float convertDpToPixel(float dp, Context context) {
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float px = dp * (metrics.densityDpi / 160f);
    return Math.round(px);
}


// for  getting in terms of Integer

private int convertPxToDp(int px, Context context) {
    Resources resources = context.getResources();
    return Math.round(px / (resources.getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
}


private int convertDpToPx(int dp, Context context) {
    Resources resources = context.getResources();

    return Math.round(dp * (resources.getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));

}

______________________________________________________________________________

public static float convertPixelsToDp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}

public static float convertDpToPixel(float dp){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float px = dp * (metrics.densityDpi / 160f);
    return Math.round(px);
}


private int convertDpToPx(int dp){
    return Math.round(dp*(getResources().getDisplayMetrics().xdpi/DisplayMetrics.DENSITY_DEFAULT));

}

private int convertPxToDp(int px){
    return Math.round(px/(Resources.getSystem().getDisplayMetrics().xdpi/DisplayMetrics.DENSITY_DEFAULT));
}
1
Trinadh Koya

DP、SP、インチ、ミリメートル、ポイントまたはピクセルを異なる画面密度で相互に変換するためのオンライン計算機を探している場合、 これは私が知っている最も完全なツールです

1
Paul Lammertsma

上記の回答は完全に正確ではありません。 Androidソースコードを検査して得られた情報によると:

Resources.getDimension()getDimensionPixelOffset()/getDimensionPixelSize()は、前者がfloatを返し、後者2つがintに適切に丸められた同じ値を返すという点でのみ異なります。それらすべてについて、戻り値は生のピクセルです。

3つすべての関数は、Resources.getValue()を呼び出し、TypedValue.complexToDimension()TypedValue.complexToDimensionPixelOffset()TypedValue.complexToDimensionPixelSize()をそれぞれ呼び出して、TypedValueを変換することにより実装されます。

したがって、XMLソースで指定されたユニットとともに「生の」値を取得する場合は、Resources.getValue()を呼び出して、TypedValueクラスのメソッドを使用します。

0
Jaromír Adamec

他の回答の助けを借りて、私はこの関数を書きました。

public static int convertToPixels(Context context, int nDP)
{
        final float conversionScale = context.getResources().getDisplayMetrics().density; 
        return (int) ((nDP * conversionScale) + 0.5f) ;
}
0
Abhishek

Kotlin拡張機能を使用して他の方法を実行する方法を次に示します。

val Int.dpToPx: Int
    get() = Math.round(this * Resources.getSystem().displayMetrics.density)

val Int.pxToDp: Int
    get() = Math.round(this / Resources.getSystem().displayMetrics.density)

そして、それはどこからでもこのように使用することができます

12.dpToPx

244.pxToDp
0
Quinn

DisplayMetrics displayMetrics = contaxt.getResources().getDisplayMetrics();

    int densityDpi = (int) (displayMetrics.density * 160f);
    int ratio = (densityDpi / DisplayMetrics.DENSITY_DEFAULT);
    int px;
    if (ratio == 0) {
        px = dp;
    } else {
        px = Math.round(dp * ratio);

    }
0
Sushil Mittal

私が書いたこの方法を自由に使用してください:

int dpToPx(int dp)
{
    return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
}
0
Ben Kane

上記のct_robsのバリエーションでは、整数を使用している場合、0で除算することを回避するだけでなく、小さなデバイスでも有用な結果を生成します。

最大精度の除算を含む整数計算では、切り捨ての影響を減らすために除算する前に最初に乗算します。

px = dp * dpi/160 dp = px * 160/dpi

5 * 120 = 600/160 = 3

の代わりに

5 *(120/160 = 0)= 0

丸めた結果が必要な場合は、これを行います

px =(10 * dp * dpi/160 + 5)/ 10 dp =(10 * px * 160/dpi + 5)/ 10

10 * 5 * 120 = 6000/160 = 37 + 5 = 42/10 = 4

0
user2624395