Формула от px до dp, от dp до px android - PullRequest
143 голосов
/ 29 ноября 2011

Я пытаюсь вычислить переменное количество пикселей для плотности независимых пикселей и наоборот.

Эта формула (px to dp): dp = (int)(px / (displayMetrics.densityDpi / 160)); не работает на небольших устройствах, потому что она делится на ноль.

Это моя формула dp to px:

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

Может кто-нибудь дать мне несколько советов?

Ответы [ 19 ]

1 голос
/ 11 июня 2014

Если вам нужен онлайн-калькулятор для преобразования DP, SP, дюймов, миллиметров, точек или пикселей друг в друга при разной плотности экрана, это наиболее полный из известных мне инструментов.

1 голос
/ 29 ноября 2011

Вы можете использовать [DisplayMatrics][1] и определить плотность экрана.Примерно так:

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

Насколько я помню, лучше использовать настил для смещения и округления для ширины.

1 голос
/ 21 сентября 2016

// для получения в виде десятичного числа / числа с плавающей запятой

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));
}
0 голосов
/ 05 января 2016

с помощью других ответов я написал эту функцию.

public static int convertToPixels(Context context, int nDP)
{
        final float conversionScale = context.getResources().getDisplayMetrics().density; 
        return (int) ((nDP * conversionScale) + 0.5f) ;
}
0 голосов
/ 01 февраля 2015

вариант ответа 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 голосов
/ 17 сентября 2014

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 голосов
/ 11 июля 2013

Не стесняйтесь использовать этот метод, я написал:

int dpToPx(int dp)
{
    return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
}
0 голосов
/ 28 марта 2019

Вот другой способ сделать это с помощью расширений 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 голосов
/ 01 сентября 2014

Ответ, принятый выше, не является полностью точным. Согласно информации, полученной при проверке исходного кода Android:

Resources.getDimension() и getDimensionPixelOffset() / getDimensionPixelSize() отличаются только тем, что первое возвращает float, в то время как два последних возвращают одинаковое значение, округленное до int соответственно. Для всех них возвращаемое значение в необработанных пикселях.

Все три функции реализуются путем вызова Resources.getValue() и преобразования полученных таким образом TypedValue путем вызова TypedValue.complexToDimension(), TypedValue.complexToDimensionPixelOffset() и TypedValue.complexToDimensionPixelSize() соответственно.

Поэтому, если вы хотите получить «необработанное» значение вместе с единицей, указанной в источнике XML, вызовите Resources.getValue() и используйте методы класса TypedValue.

...