web-dev-qa-db-fra.com

Quelle est la bonne façon de spécifier les dimensions dans DIP à partir de Java code?

J'ai trouvé qu'il est possible de définir les dimensions de mes éléments d'interface dans des dispositions XML à l'aide de DIP comme dans le fragment suivant:

Android:layout_width="10dip"

Mais toutes les interfaces Java prennent l'entier comme arguments et il n'y a aucun moyen de spécifier les dimensions dans les DIP. Quelle est la bonne façon de calculer cela?

J'ai pensé que je devais utiliser la densité de propriété de la classe DisplayMetrics mais est-ce une bonne façon?

Puis-je compter sur le fait que cette formule est toujours correcte?

pixels * DisplayMetrics.density = dip

Existe-t-il une fonction utilitaire pour la conversion quelque part dans Android?

51
Pavel Lahoda

Il existe une méthode utilitaire existante appelée TypedValue.applyDimensions(int, float, DisplayMetrics) qui fait cela.

Voici comment l'utiliser:

// returns the number of pixels for 123.4dip
int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 
                     (float) 123.4, getResources().getDisplayMetrics());

Il existe une liste d'autres types que vous pouvez utiliser, notamment COMPLEX_UNIT_SP, COMPLEX_UNIT_PT tout trouvé dans la page que j'ai liée ci-dessus. Si vous excluez le transtypage (int), vous obtiendrez le nombre à virgule flottante.

J'ai rencontré le même problème et j'ai trouvé cela en fouillant le code.

91
sirhc

C'est là la bonne formule. Bien que DisplayMetrics.density n'est pas un membre statique, donc, selon le même document auquel vous avez fait allusion , l'utilisation correcte est:

// Maybe store this in a static field?
final float SCALE = getContext().getResources().getDisplayMetrics().density;

// Convert dips to pixels
float valueDips = 16.0f;
int valuePixels = (int)(valueDips * SCALE + 0.5f); // 0.5f for rounding
45
Roman Nurik

En utilisant le champ de densité des métriques d'affichage, vous pouvez obtenir un facteur d'échelle à convertir vers/à partir des immersions. Utilisez la méthode Math.round pour convertir d'un float en un int sans avoir besoin de transtypage ni ajouter 0,5

// Converting dips to pixels
float dips = 20.0f;
float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = Math.round(dips * scale);

// Converting pixels to dips
int pixels = 15;
float scale = getContext().getResources().getDisplayMetrics().density;
float dips = pixels / scale;
9
Matt Stoker

Je pense que le meilleur moyen n'est pas de définir des dimensions dans le code, mais d'utiliser le values/dimens.xml fichier à la place. Vous pouvez toujours définir votre dimension dans l'unité souhaitée comme:

<dimen name="my_layout_height">120dp</dimen>

puis faites référence à ceci dans votre activité comme:

getResources().getDimensions(R.dimen.my_layout_height);

Cela retournerait pixels après avoir effectué les conversions nécessaires. Et bien sûr, vous pouvez également faire référence à cela dans vos autres XML comme:

Android:layout_width="@dimen/my_layout_height"
5
ercan