Intereting Posts
Масштабирование фонового изображения в LinearLayout В файле R отсутствует андроид Тип ошибки 3. Класс активности {com.awesome_project / com.awesome_project.MainActivity} не существует в реакции native (Android-устройство) Подходящее устройство Android для инженерного проекта Определите алгоритм шифрования GSM Переполнение буфера GsaIOException, отсутствие свободного места Внутренние классы: Android против Java Типированный массив должен быть переработан после использования с #recycle () Нарисуйте текст в круговом виде? Google Play – разница между низкой степенью зрелости и средней зрелостью Как я могу заставить Слушать Игровые Службы автоматически не войти в систему при запуске? Как отключить push-уведомление от отображения при запуске приложения? AlphabetIndexer с пользовательским адаптером Как я могу записать голос и записать Call в Android? Неисправность Backstack активности при разрушении деятельности

Формула px для dp, dp to px android

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

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

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

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

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

Solutions Collecting From Web of "Формула px для dp, dp to px android"

Примечание. Широко используемое выше решение основано на displayMetrics.density . Однако в документах объясняется, что это значение представляет собой округленное значение, используемое с экранными «ведрами». Например. На моем Nexus 10 он возвращает 2, где реальное значение будет 298dpi (real) / 160dpi (по умолчанию) = 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 на dp:

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

Px на dp:

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

Просто позвоните getResources().getDimensionPixelSize(R.dimen.your_dimension) для преобразования из единиц dp в пиксели

Использовать эту функцию

 private int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); } 

Эффективный путь

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

Надеюсь, что это поможет вам.

 px = dp * (dpi / 160) dp = px * (160 / dpi) 

В большинстве случаев функции преобразования часто вызываются. Мы можем оптимизировать его, добавив memoization. Таким образом, он не вычисляет каждый раз, когда функция вызывается.

Объявим 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; } 

Функция memoization, которая возвращает значение из 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)); } 

Благодарю.

Ниже funtions работал хорошо для меня на разных устройствах.

Он взят из 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 . Для всех из них возвращаемое значение находится в необработанных пикселях.

Все три функции реализованы путем вызова 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

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

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