2011-01-05 5 views
629

Я создал свое приложение с высотой и шириной, заданными в пикселях для устройства Pantech с разрешением 480x800.Преобразование пикселей в dp

Мне нужно преобразовать высоту и ширину для устройства G1. Я думал, что преобразование его в dp решит проблему и обеспечит такое же решение для обоих устройств.

Есть ли простой способ преобразования пикселей в dp? Любые предложения?

+1

Если вы хотите делать одноразовое преобразование (например, для экспорта спрайты из Photoshop), [здесь отличный конвертер] (http://pixplicity.com/dp-px-converter/). –

+0

['px',' dp', 'sp' conversion formula] (https://stackoverflow.com/a/42108115/3681880) – Suragch

ответ

5

Вы должны использовать dp так же, как и пиксели. Это все, что они есть; отображать независимые пиксели. Используйте те же номера, что и на экране со средней плотностью, и размер будет волшебным образом на экране с высокой плотностью.

Однако, это звучит так, как вам нужно, это опция fill_parent в вашем дизайне макета. Используйте fill_parent, когда вы хотите, чтобы ваш просмотр или элемент управления расширялся до всего оставшегося размера в родительском контейнере.

+0

На самом деле моя проблема заключается в том, что мое приложение закодировано для экрана с высокой плотностью, и теперь оно должно быть преобразованный в экран с низкой плотностью. – Indhu

+0

измените свои пиксели для экрана средней плотности (вы можете настроить экран средней плотности в эмуляторе) и заменить пиксель на dp. Тем не менее, более гибкие приложения могут быть выполнены с использованием fill_parent и нескольких макетов. –

+0

Наконец, у меня не было выбора, но чтобы изменить все px на dp вручную .. :( – Indhu

849
/// Converts 14 dip into its equivalent px 

Resources r = getResources(); 
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, r.getDisplayMetrics()); 
+250

Примечание: вышеперечисленное преобразует DIP в пиксели. Первоначальный вопрос спросил, как конвертировать пиксели в Dips! –

+11

Вот реальный ответ на OP: http://stackoverflow.com/questions/6656540/android-convert-px-to-dp-video-aspect-ratio – qix

+88

Свое смешное как ответ более полезен когда он не делает действительно ответьте на вопрос -_- Я думал, что хочу, что задал вопрос, тогда я понял, что нет! Такой отличный ответ. У меня есть вопрос. Как я могу получить последний параметр для 'applyDimension'? Могу ли я просто сделать getResource(). GetDisplayMetrics() ', или есть что-то еще? – Andy

2

PX и DP разные, но похожи.

DP - это разрешение, когда вы определяете только физический размер экрана. Когда вы используете DP, он будет масштабировать ваш макет на другие экраны подобного размера с различными значениями плотности pixel.

Иногда вы действительно хотите pixels, хотя, когда вы имеете дело с измерениями в коде, вы всегда имеете дело с реальным pixels, если вы не конвертируете их.

Так на устройстве для андроидов, нормальный размер hdpi экран, 800x480 is 533x320 в DP (я считаю). Чтобы преобразовать DP в pixels /1.5, конвертировать обратно *1.5. Это только для одного размера экрана и dpi, это изменится в зависимости от дизайна. Наши художники дают мне pixels, хотя и я конвертирую в DP с приведенным выше уравнением 1.5.

77

Согласно Руководству по развитию Android:

px = dp * (dpi/160) 

Но часто вы хотите выполнить это наоборот, когда вы получаете дизайн, который заявил в пикселях. Итак:

dp = px/(dpi/160) 

Если вы на 240dpi устройстве это соотношение 1,5 (как указано выше), так что это означает, что значок 60px равна 40dp в приложении.

+2

Indhu, вы можете обратиться сюда http://developer.android.com/guide/practices/screens_support.HTML # Провалы-PELs и http://developer.android.com/reference/android/util/DisplayMetrics.html#density – Sachchidanand

+2

160 постоянен, кровать ответ – user25

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

density равна

  • .75 на ldpi (120 точек на дюйм)
  • 1.0 на mdpi (160 точек на дюйм; базовый)
  • 1.5 на hdpi (240 точек на дюйм)
  • 2.0 на xhdpi (320 точек на дюйм)
  • 3.0 на xxhdpi (480 точек на дюйм)
  • 4.0 на xxxhdpi (640 точек на дюйм)

Используйте эту online converter поиграться со значениями точек на дюйм.

EDIT: Кажется, что нет отношения 1: 1 между dpi ведром и density. Похоже, что Nexus 5X находится в состоянии xxhdpi имеет значение density2.625 (вместо 3). Посмотрите сами в Device Metrics.

+3

«Похоже, что Nexus 5X xxhdpi имеет значение плотности 2,6 (вместо 3) ». Технически Nexus 5X составляет 420 точек на дюйм, а Nexus 6/6P - 560 точек на дюйм, и не попадает прямо в один из стандартных ковшей, как и Nexus 7 с tvdpi (213dpi) , Таким образом, сайт, содержащий список xxdpi и xxxhdpi, является фарсом. Ваша диаграмма правильная, и эти устройства будут правильно масштабироваться на основе своих «специальных» тэгов. –

690
/** 
* 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){ 
    Resources resources = context.getResources(); 
    DisplayMetrics metrics = resources.getDisplayMetrics(); 
    float px = dp * ((float)metrics.densityDpi/DisplayMetrics.DENSITY_DEFAULT); 
    return px; 
} 

/** 
* 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){ 
    Resources resources = context.getResources(); 
    DisplayMetrics metrics = resources.getDisplayMetrics(); 
    float dp = px/((float)metrics.densityDpi/DisplayMetrics.DENSITY_DEFAULT); 
    return dp; 
} 
+135

Используйте'Resources.getSystem(). GetDisplayMetrics() ', если у вас нет контекста. – TomTasche

+1

Это более правильный ответ. Хорошая работа @Muhammad Nabeel Arif – Seth

+9

почему деление на 160f? –

36

Таким образом, можно использовать следующую составителю, чтобы вычислить нужное количество пикселей из измерения, указанной в дп

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

Это преобразует dp в пиксели, но вы вызвали ваш метод 'convertToDp'. – Qwertie

+1

+1 для + 0.5f :) – l33t

+4

почему + 0.5f? –

249

Предпочтительно положить в классе 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; 
} 
+1

Это хорошо работает. правильный ответ для любых устройств. –

5

В Если вы разрабатываете критичное для производительности приложение, пожалуйста, рассмотрите следующий оптимизированный класс:

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

Это происходит только в том случае, если вы делаете преобразования очень часто. В моем случае я это делаю. –

+0

Что такое 160f? Почему вы используете его, почему это 160? – definera

+0

160 => 160dpi, и это предназначено для преобразования мер из-за формулы – xAqweRx

4

Вот как это работает для меня:

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

Вы можете сделать то же самое для ширины.

61

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

'Resources.getSystem()' javadoc говорит: «Возвращает глобальный общий ресурс« Ресурсы », который обеспечивает доступ только к системным ресурсам (без ресурсов приложения) и не настроен для текущий экран (не может использовать единицы измерения, не изменяется в зависимости от ориентации и т. д.) ». Это в значительной степени говорит, что вы не должны этого делать, даже если это работает. –

+0

Я только что прочитал комментарий @ AustynMahoney и понял, что этот ответ не так велик, как я изначально думал, но [SO не позволит мне отменить мой upvote] (http://meta.stackexchange.com/q/80762/302619) ! Argh! –

+2

не работает. Неправильно. –

62

Если вы можете использовать размеры 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); 
+1

Это лучшее решение. Спасибо. –

+1

Это должен быть выбранный ответ. – TomTaila

+0

Это лучший ответ. –

4

преобразовать Пиксели в дп использовать 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()); 

Надежда, что помогает.

+0

Это пиксель для преобразования пикселей тоже ... – superuser

29

Существует по умолчанию Util в Android SDK: http://developer.android.com/reference/android/util/TypedValue.html

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

Вы должны использовать этот. В качестве бонуса также будет SP. –

+1

'resultPix' должен иметь тип int. 'int resultPix = (int) TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_DIP, 1, getResources(). getDisplayMetrics())' – vovahost

+0

Это должен быть принятый ответ – momo

5

так:

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

9

Возможно, лучший способ i f у вас есть размер внутри значений/dimen, чтобы получить размер непосредственно из метода getDimension(), он вернет вам измерение, уже преобразованное в значение пикселя.

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

Просто, чтобы лучше объяснить это,

getDimension(int resourceId) 

возвращает размер уже преобразуется в пиксель поплавком.

getDimensionPixelSize(int resourceId) 

возвратит то же, но усеченный в целом, так КАЧЕСТВЕ INTEGER.

См Android reference

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

Это не то же самое, что и во многих других ответах этот вопрос? – TZHX

36

Для DP to Pixel

Создайте значение в dimens.xml

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

Получите это значение в pixel как:

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

это лучшее решение. должен быть первым ответом – itzhar

-3

Для преобразования dp to px этот код может быть полезным:

public static int dpToPx(Context context, int dp) { 
     int px = Math.round(dp * getPixelScaleFactor(context)); 
     return px; 
    } 
    private static float getPixelScaleFactor(Context context) { 
     DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 
     return (displayMetrics.xdpi/DisplayMetrics.DENSITY_DEFAULT); 
    } 
+0

Не работает .. –

10
Для преобразования дп в пикселе.
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().

+6

Ответ неправильный, потому что вы не конвертируете пиксели в dp - вы конвертируете пиксели в пиксели! – Yaroslav

0

Это workds для меня (C#):

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

Не ответ на этот вопрос, но для C# он работает. Спасибо –

52

Вы можете использовать это .. без контекста

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

Возможно, вы не захотите это использовать. Документация для getSystem() - «Возвращение глобального общего ресурса, который предоставляет доступ только к системным ресурсам (без ресурсов приложения) и не настроен для текущего экрана (не может использовать единицы измерения, не изменяется в зависимости от ориентации и т. Д.). «. – Stan

3

Более элегантный подход с использованием функции расширения Котлин в

/** 
* 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}") 
+0

'16.px' На самом деле, значит, не 16, а не px, lol. – Slava

+0

Люблю использование расширения здесь. Я читал функции как «конвертировать в« имя функции », которые я понимаю в этом случае назад. Чтобы уточнить намерение каждой функции, имена функций могут быть обновлены для чтения dpToPx и pxToDp, соответственно. – Maxwell

10

Для тех, кто с помощью Котлин:

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