android - pixeles - Convertir píxeles a dp
px to dp java (30)
He creado mi aplicación con la altura y el ancho dados en píxeles para un dispositivo Pantech cuya resolución es 480x800.
Necesito convertir la altura y el ancho para un dispositivo G1. Pensé que convertirlo en dp resolverá el problema y proporcionará la misma solución para ambos dispositivos.
¿Hay alguna manera fácil de convertir píxeles a dp? ¿Alguna sugerencia?
Kotlin
fun convertDpToPixel(dp: Float, context: Context): Float {
return dp * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
fun convertPixelsToDp(px: Float, context: Context): Float {
return px / (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
Java
public static float convertDpToPixel(float dp, Context context) {
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
public static float convertPixelsToDp(float px, Context context) {
return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
Así es como funciona para mí:
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int h = displaymetrics.heightPixels;
float d = displaymetrics.density;
int heightInPixels=(int) (h/d);
Puedes hacer lo mismo para el ancho.
Deberías usar dp tal como lo harías con los píxeles. Eso es todo lo que son; mostrar píxeles independientes. Use los mismos números que usaría en una pantalla de densidad media, y el tamaño será mágicamente correcto en una pantalla de alta densidad.
Sin embargo, parece que lo que necesita es la opción fill_parent en el diseño de su diseño. Use fill_parent cuando desee que su vista o control se expanda a todo el tamaño restante en el contenedor principal.
En caso de que esté desarrollando una aplicación de rendimiento crítico, considere la siguiente clase optimizada:
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;
}
}
Esto debería darle la conversión dp a píxeles:
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
Esto debería darle los píxeles de conversión a dp:
public static int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
Esto funciona para mi (C #):
int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);
Hay una utilidad predeterminada en el SDK de Android: http://developer.android.com/reference/android/util/TypedValue.html
float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
Kotlin
fun spToPx(ctx: Context, sp: Float): Float {
return sp * ctx.resources.displayMetrics.scaledDensity
}
fun pxToDp(context: Context, px: Float): Float {
return px / context.resources.displayMetrics.density
}
fun dpToPx(context: Context, dp: Float): Float {
return dp * context.resources.displayMetrics.density
}
Java
public static float spToPx(Context ctx,float sp){
return sp * ctx.getResources().getDisplayMetrics().scaledDensity;
}
public static float pxToDp(final Context context, final float px) {
return px / context.getResources().getDisplayMetrics().density;
}
public static float dpToPx(final Context context, final float dp) {
return dp * context.getResources().getDisplayMetrics().density;
}
Me gusta esto:
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;
}
}
Depende del contexto, devuelve valor flotante, método estático
Muchas grandes soluciones arriba. Sin embargo, la mejor solución que encontré es el diseño de google:
Para Xamarin.Android
float DpToPixel(float dp)
{
var resources = Context.Resources;
var metrics = resources.DisplayMetrics;
return dp * ((float)metrics.DensityDpi / (int)DisplayMetricsDensity.Default);
}
Hacer que esto sea no estático es necesario cuando se crea un renderizador personalizado.
Para cualquiera que use Kotlin:
val Int.toPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
Uso:
64.toPx
32.toDp
Por lo tanto, puede utilizar el siguiente formulador para calcular la cantidad correcta de píxeles de una dimensión especificada en dp
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);
}
Preferiblemente poner en una clase 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;
}
Probablemente la mejor manera si tiene la dimensión dentro de los valores / dimen es obtener la dimensión directamente del método getDimension (), le devolverá la dimensión ya convertida en valor de píxel.
context.getResources().getDimension(R.dimen.my_dimension)
Solo para explicar mejor esto,
getDimension(int resourceId)
devolverá la dimensión ya convertida a píxel COMO UN FLOTADOR.
getDimensionPixelSize(int resourceId)
devolverá lo mismo pero truncado a int, por lo tanto, COMO UN INTEGER.
Puedes usar esto ... sin contexto
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);
}
Como mencionó @Stan, el uso de este enfoque puede causar problemas si el sistema cambia la densidad. ¡Así que sé consciente de eso!
Personalmente estoy usando contexto para hacer eso.
Según la Guía de Desarrollo de Android:
px = dp * (dpi / 160)
Pero a menudo querrá realizar esto al revés cuando reciba un diseño que se indica en píxeles. Asi que:
dp = px / (dpi / 160)
Si está en un dispositivo de 240 ppp, esta relación es de 1.5 (como se indicó anteriormente), por lo que esto significa que un ícono de 60px equivale a 40dp en la aplicación.
Si desea valores enteros , al usar Math.round () redondeará el valor flotante al entero más cercano.
public static int pxFromDp(final float dp) {
return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
}
Si puedes usar las dimensiones XML es muy simple!
En su res/values/dimens.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="thumbnail_height">120dp</dimen>
...
...
</resources>
Entonces en tu Java:
getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
Sin Context
, elegantes métodos estáticos:
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);
}
Un enfoque más elegante utilizando la función de extensión de Kotlin.
/**
* 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()
Uso:
println("16 dp in pixel: ${16.dpToPx}")
println("16 px in dp: ${16.pxToDp}")
para convertir píxeles a dp utiliza el valor de http://developer.android.com/reference/android/util/TypedValue.html .
Como se mencionó en la documentación: Contenedor para un valor de datos tipificados dinámicamente.
y usa el método applyDimension :
public static float applyDimension (int unit, float value, DisplayMetrics metrics)
que convierte un valor de datos complejos desempaquetado que mantiene una dimensión a su valor de punto flotante final como el siguiente:
Resources resource = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics());
Espero que ayude .
PX
y DP
son diferentes pero similares.
DP
es la resolución cuando solo factorizas el tamaño físico de la pantalla. Cuando use DP
, escalará su diseño a otras pantallas de tamaño similar con diferentes densidades de pixel
.
Sin embargo, de vez en cuando realmente desea pixels
, y cuando trata con dimensiones en el código, siempre está tratando con pixels
reales, a menos que los convierta.
Así que en un dispositivo Android, pantalla hdpi
tamaño normal, 800x480 is 533x320
en DP
(creo). Para convertir DP
en pixels /1.5
, para volver a convertir *1.5
. Esto es solo para el tamaño de una pantalla y dpi
, cambiaría dependiendo del diseño. Sin embargo, nuestros artistas me dan pixels
y me convierto a DP
con la ecuación de 1.5
anterior.
Para DP to Pixel
Crear un valor en dimens.xml
<dimen name="textSize">20dp</dimen>
Consigue ese valor en pixel
como:
int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);
((MyviewHolder) holder).videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(final MediaPlayer mediaPlayer) {
mediaPlayer.setLooping(true);
((MyviewHolder) holder).spinnerView.setVisibility(View.GONE);
mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
/*
* add media controller
*/
MediaController controller = new MediaController(mContext);
float density = mContext.getResources().getDisplayMetrics().density;
float px = 55 * density;
// float dp = somePxValue / density;
controller.setPadding(0, 0, 0, (int) (px));
((MyviewHolder) holder).videoView.setMediaController(controller);
}
});
}
});
/**
* 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){
return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;
density
es igual
-
.75
enldpi
(120
dpi) -
1.0
enmdpi
(160
dpi; línea de base) -
1.5
enhdpi
(240
dpi) -
2.0
enxhdpi
(320
dpi) -
3.0
enxxhdpi
(480
dpi) -
4.0
enxxxhdpi
(640
dpi)
Utilice este convertidor en línea para jugar con los valores de ppp.
EDITAR: Parece que no hay una relación 1: 1 entre el cubo de dpi
y la density
. Parece que el Nexus 5X
siendo xxhdpi
tiene un valor de density
de 2.625
(en lugar de 3
). Compruébelo usted mismo en la Métrica del dispositivo .
float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);
public static int dp2px(Resources resource, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,resource.getDisplayMetrics());
}
Para convertir pixel a dp.
public static float px2dp(Resources resource, float px) {
return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}
donde recurso es context.getResources ().