Формула РХ на DP, DP в px для Андроид
Я пытаюсь вычислить количество пикселей в плотность независимых пикселей и наоборот.
эта формула (px to dp): dp = (int)(px / (displayMetrics.densityDpi / 160));
не работает на небольших устройствах, потому что он делится на ноль.
Это моя формула dp to px:
px = (int)(dp * (displayMetrics.densityDpi / 160));
может кто-нибудь дать мне несколько советов?
18 ответов:
Примечание: широко используемое решение выше основано на
displayMetrics.density
. Однако документы объясняют, что это значение является округленным значением, используемым с экраном "ведра". Например. на моем Nexus 10 он возвращает 2, где реальное значение будет 298dpi (real) / 160dpi (default) = 1.8625.в зависимости от ваших потребностей, вам может понадобиться точное преобразование, которое может быть достигнуто следующим образом:
[Edit] это не должно быть смешано с внутренним блоком dp Android, так как это курс по-прежнему основан на экранных ведрах. Используйте это там, где вы хотите, чтобы устройство отображало один и тот же реальный размер на разных устройствах.
конвертировать 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, которые вы можете различать, но я не могу представить себе нормальный дисплей, где эти значения сильно отличаются.
Я решил свою проблему, используя следующие формулы. Пусть другие люди извлекут из этого пользу.
dp to px:
displayMetrics = context.getResources().getDisplayMetrics(); return (int)((dp * displayMetrics.density) + 0.5);
px to dp:
displayMetrics = context.getResources().getDisplayMetrics(); return (int) ((px/displayMetrics.density)+0.5);
px to dp:
int valueInpx = ...; int valueInDp= (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, valueInpx , getResources() .getDisplayMetrics());
просто позвони
getResources().getDimensionPixelSize(R.dimen.your_dimension)
для преобразования изdp
единицы в пикселях
эффективный способ когда-либо
DP в пиксель:
private int dpToPx(int dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); }
Pixel to DP:
private int pxToDp(int px) { return (int) (px / Resources.getSystem().getDisplayMetrics().density); }
надеюсь, что это поможет вам.
используйте эту функцию
private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); }
в большинстве случаев часто вызываются функции преобразования. Мы можем оптимизировать его, добавив мемоизация. Таким образом, он не вычисляет каждый раз, когда функция вызывается.
объявим хэш-карту, которая будет хранить вычисленные значения.
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; }
функция memoization, которая возвращает значение из HashMap и поддерживает запись предыдущих значений.
Memoization может быть реализованы по-разному в 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)); }
спасибо.
попробуйте это http://labs.skinkers.com/content/android_dp_px_calculator/
ниже функции хорошо работали для меня на разных устройствах.
он взят из 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); }
// для получения в терминах 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)); }
Если вы ищете онлайн-калькулятор для преобразования DP, SP, дюймов, миллиметров, точек или пикселей друг в друга и друг от друга при разных плотностях экрана, Это самый полный инструмент, который я знаю.
можно использовать
[DisplayMatrics][1]
и определить плотность экрана. Что-то вроде этого:int pixelsValue = 5; // margin in pixels float d = context.getResources().getDisplayMetrics().density; int margin = (int)(pixelsValue * d);
Как я помню, лучше использовать настил для смещений и округления по ширине.
Не стесняйтесь использовать этот метод, я писал:
int dpToPx(int dp) { return (int) (dp * getResources().getDisplayMetrics().density + 0.5f); }
ответ, принятый выше, не является полностью точным. Согласно информации, полученной при проверке исходного кода Android:
Resources.getDimension()
иgetDimensionPixelOffset()
/getDimensionPixelSize()
отличаются только тем, что первый возвращаетfloat
в то время как последние два возвращают одно и то же значение, округленное доint
appropriatelly. Для всех из них возвращаемое значение находится в необработанных пикселях.все три функции реализуются путем вызова
Resources.getValue()
и преобразование полученного таким образомTypedValue
по телефонуTypedValue.complexToDimension()
,TypedValue.complexToDimensionPixelOffset()
иTypedValue.complexToDimensionPixelSize()
, соответственно.поэтому, если вы хотите получить "сырое" значение вместе с единицей, указанной в источнике XML, вызовите
Resources.getValue()
и использовать методыTypedValue
класса.
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); }
вариация на 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