Conversion des pixels en dp
j'ai créé mon application avec la hauteur et la largeur données en pixels pour un périphérique Pantech dont la résolution est de 480x800.
je dois convertir la hauteur et la largeur pour un appareil G1. Je pensais que le convertir en dp résoudrait le problème et fournirait la même solution pour les deux appareils.
y a-t-il un moyen facile de convertir les pixels en dp? des suggestions?
30 réponses
// 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);
}
de préférence mis dans un Util.classe 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;
}
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;
density
égale
-
.75
surldpi
(120
ppp) -
1.0
surmdpi
(160
dpi; la ligne de base) -
1.5
surhdpi
(240
ppp) -
2.0
surxhdpi
(320
ppp) -
3.0
surxxhdpi
(480
ppp) -
4.0
surxxxhdpi
(640
ppp)
utilisez cette convertisseur en ligne pour jouer avec les valeurs dpi.
EDIT:
Il semble qu'il n'y ait pas de relation 1:1 entre dpi
bucket et density
. On dirait que le Nexus 5X
étant xxhdpi
a une valeur density
de 2.625
(au lieu de 3
). Voyez vous - même dans les paramètres de périphérique .
selon le guide de développement Android:
px = dp * (dpi / 160)
mais souvent vous voudrez effectuer cela l'inverse quand vous recevez un design qui est indiqué en pixels. So:
dp = px / (dpi / 160)
si vous êtes sur un périphérique 240dpi ce rapport est de 1,5 (comme indiqué précédemment), donc cela signifie qu'une icône de 60px égale 40dp dans la demande.
si vous pouvez utiliser les dimensions XML c'est très simple!
dans votre res/values/dimens.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="thumbnail_height">120dp</dimen>
...
...
</resources>
puis dans votre Java:
getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
sans Context
, élégantes méthodes statiques:
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);
}
vous pouvez utiliser ceci .. sans contexte
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);
}
pour DP to Pixel
créer une valeur dans dimens.xml
<dimen name="textSize">20dp</dimen>
obtenir cette valeur dans pixel
comme:
int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);
vous pouvez donc utiliser le formulateur suivant pour calculer la bonne quantité de pixels à partir d'une dimension spécifiée dans 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);
}
il y a un util par défaut dans android SDK: http://developer.android.com/reference/android/util/TypedValue.html
float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
pour toute personne utilisant Kotlin:
val Int.toPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
Utilisation:
64.toPx
32.toDp
cela devrait vous donner la conversion dp en pixels:
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
cela devrait vous donner les pixels de conversion en 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());
}
Pour convertir pixel en dp.
public static float px2dp(Resources resource, float px) {
return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}
où la ressource est le contexte.getResources().
probablement la meilleure façon si vous avez la dimension inside values/dimen est d'obtenir la dimension directement à partir de la méthode getDimension (), il vous retournera la dimension déjà convertie en valeur de pixel.
context.getResources().getDimension(R.dimen.my_dimension)
Juste pour mieux expliquer cela,
getDimension(int resourceId)
renverra la dimension déjà convertie en pixel comme flotteur.
getDimensionPixelSize(int resourceId)
retournera le même mais tronqué à int, de sorte que ENTIER.
voir référence Android
comme ceci:
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;
}
}
dépend du Contexte, de retour float valeur, la méthode statique
dans le cas où vous développez une application critique de performance, s'il vous plaît considérer la classe optimisée suivante:
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);
C'est comme ça que ça marche pour moi:
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int h = displaymetrics.heightPixels;
float d = displaymetrics.density;
int heightInPixels=(int) (h/d);
vous pouvez faire la même chose pour la largeur.
vous devez utiliser dp tout comme vous pixels. C'est tout ce qu'ils sont; affichez des pixels indépendants. Utilisez les mêmes nombres que vous feriez sur un écran de densité moyenne, et la taille sera magiquement correcte sur un écran de haute densité.
cependant, il semble que ce dont vous avez besoin est l'option fill_parent dans votre layout design. Utilisez fill_parent lorsque vous voulez que votre vue ou votre contrôle s'étende à toute la taille restante dans le conteneur parent.
pour convertir les Pixels en dp utilisez la TypedValue .
comme indiqué dans la documentation : conteneur pour une valeur de données dactylographiée dynamiquement .
et utiliser la applyDimension méthode:
public static float applyDimension (int unit, float value, DisplayMetrics metrics)
qui convertit une valeur de données complexes non emballée contenant une dimension à sa valeur finale en virgule flottante comme suit:
Resources resource = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics());
Hope qui Permet de .
approche plus élégante utilisant la fonction d'extension 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()
Utilisation:
println("16 dp in pixel: ${16.dpToPx}")
println("16 px in dp: ${16.pxToDp}")
beaucoup de grandes solutions ci-dessus. Cependant, la meilleure solution que j'ai trouvé est la conception de google:
PX
et DP
sont différents mais similaires.
DP
est la résolution lorsque vous seul facteur de la taille physique de l'écran. Lorsque vous utilisez DP
, il vous permettra d'adapter votre disposition à d'autres écrans de taille similaire avec des densités pixel
différentes.
de temps en temps vous voulez réellement pixels
cependant, et quand vous traitez avec les dimensions dans le code, vous êtes toujours en train de traiter avec le réel pixels
, à moins que vous les convertir.
donc sur un appareil android, taille normale hdpi
écran, 800x480 is 533x320
dans DP
(je crois). Pour convertir DP
en pixels /1.5
, pour convertir *1.5
. Ce n'est que pour la taille d'écran unique et dpi
, il changerait en fonction de la conception. Nos artistes me donnent pixels
et je convertis en DP
avec l'équation ci-dessus 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);
}
Ce workds pour moi (C#):
int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);
Si vous voulez Integer valeurs à l'aide des Mathématiques.round() arrondit le flotteur à l'entier le plus proche.
public static int pxFromDp(final float dp) {
return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
}
Pour Xamarin.Android
float DpToPixel(float dp)
{
var resources = Context.Resources;
var metrics = resources.DisplayMetrics;
return dp * ((float)metrics.DensityDpi / (int)DisplayMetricsDensity.Default);
}
il est nécessaire d'en faire un non-statique lorsque vous faites un renderer personnalisé
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);
}
});
}
});