A converter pixels para dp
criei a minha aplicação com a altura e largura dadas em pixels para um dispositivo Pantech cuja resolução é 480x800.
Preciso de converter altura e largura para um dispositivo G1. Eu pensei que convertê-lo em dp vai resolver o problema e fornecer a mesma solução para ambos os dispositivos.
Existe alguma maneira fácil de converter pixels para dp?Alguma sugestão?
30 answers
// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
/**
* 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);
}
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;
}
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;
density
igual a
-
.75
emldpi
(120
PPP) {[[32]} -
1.0
emmdpi
(160
PPP; linha de base) -
1.5
emhdpi
(240
PPP) {[[32]} -
2.0
Emxhdpi
(320
PPP) {[[32]} -
3.0
emxxhdpi
(480
PPP) {[[32]} -
[17]
xxxhdpi
(640
PPP) {[[32]}
Use este Conversor online para brincar com os valores de PPP.
Editar:
Parece que não há nenhuma relação 1: 1 entre dpi
bucket e density
. Parece como o Nexus 5X
ser xxhdpi
tem um valor density
de 2.625
(em vez de 3
). Veja por si mesmo nas métricas do dispositivo .
px = dp * (dpi / 160)
Mas muitas vezes você vai querer fazer isso ao contrário quando você receber um projeto que é indicado em pixels. Então ...
dp = px / (dpi / 160)
Se estiver num dispositivo de 240ppp, esta relação é de 1, 5 (Como foi indicado anteriormente), o que significa que um ícone de 60px é igual a 40dp na aplicação.
Se você pode usar as dimensões XML é muito simples!
No seu res/values/dimens.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="thumbnail_height">120dp</dimen>
...
...
</resources>
Então na tua Java:
getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
Sem 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);
}
Podes usar isto .. sem 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);
}
Para DP to Pixel
Criar um valor em dimens.xml
<dimen name="textSize">20dp</dimen>
Obter esse valor em pixel
Como:
int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);
Pode, portanto, utilizar o seguinte formulador para calcular a quantidade correcta de pixels a partir de uma dimensão especificada em 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);
}
Existe um util por omissão no SDK android: http://developer.android.com/reference/android/util/TypedValue.html
float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
Para qualquer pessoa que utilize Kotlin:
val Int.toPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
Utilização:
64.toPx
32.toDp
Isto deve dar - lhe a conversão dp em pixels:
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
Isto deve dar-lhe os pixels de conversão para dp:
public static int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
public static int dp2px(Resources resource, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,resource.getDisplayMetrics());
}
Para converter pixel para dp.
public static float px2dp(Resources resource, float px) {
return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}
Onde o recurso é o contexto.getResources().
Provavelmente a melhor maneira se você tiver a dimensão dentro dos valores / dimen é obter a dimensão directamente a partir do método getDimension (), ele irá devolver-lhe a dimensão já convertida em valor de pixel.
context.getResources().getDimension(R.dimen.my_dimension)
Só para melhor explicar isto,
getDimension(int resourceId)
Irá devolver a dimensão já convertida em pixel como um flutuador.
getDimensionPixelSize(int resourceId)
Irá retornar o mesmo, mas truncado para int, de modo a INTEIRO.
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;
}
}
Dependendo do contexto, devolve o valor flutuante, método estático
No caso de desenvolver uma aplicação crítica de desempenho, considere a seguinte classe 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;
}
}
float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int h = displaymetrics.heightPixels;
float d = displaymetrics.density;
int heightInPixels=(int) (h/d);
Podes fazer o mesmo pela largura.
Deve usar o dp tal como faria com os pixels. Isso é tudo o que eles são; exibir pixels independentes. Use os mesmos números que você faria em uma tela de média densidade, e o tamanho será magicamente correto em uma tela de alta densidade.
No entanto, parece que o que você precisa é da opção fill_parent no seu design de layout. Use fill_ pai quando você quer que sua vista ou controle para expandir para todo o tamanho restante no container pai.Para converter Pixels para dp use o TypedValue .
Tal como a documentação mencionada : contentor para um valor de dados dinamicamente tipado .
E utilizar o método applyDimension :
public static float applyDimension (int unit, float value, DisplayMetrics metrics)
Que converte um valor complexo de dados não embalado com uma dimensão ao seu valor final de vírgula flutuante como o seguinte:
Resources resource = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics());
Espero que isso ajude .
Abordagem mais elegante usando a função de extensão do 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()
Utilização:
println("16 dp in pixel: ${16.dpToPx}")
println("16 px in dp: ${16.pxToDp}")
Um monte de grandes soluções acima. No entanto, a melhor solução que encontrei é o projeto do google:
PX
e {[1] } são diferentes, mas semelhantes.
DP
é a resolução quando você só fator o tamanho físico da tela. Quando usar DP
, irá escalar a sua disposição para outros ecrãs de tamanho semelhante com densidades diferentes pixel
.
DP
em pixels /1.5
, para converter de volta *1.5
. Isto é apenas para o tamanho de uma tela e dpi
, ele iria mudar dependendo do design. Os nossos artistas dão-me pixels
mas eu converto-me para DP
com a equação acima 1.5
.
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);
}
Isto funciona para mim (C#):
int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);
Se quiser valores inteiros , então use a matemática.round () irá arredondar o flutuador para o número inteiro mais próximo.
public static int pxFromDp(final float dp) {
return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
}
Para Xamarin.Android
float DpToPixel(float dp)
{
var resources = Context.Resources;
var metrics = resources.DisplayMetrics;
return dp * ((float)metrics.DensityDpi / (int)DisplayMetricsDensity.Default);
}
Fazer disto um não-estático é necessário quando se está a fazer um renderizador personalizado
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;
}
((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);
}
});
}
});