Charger la valeur de dimension à partir de res / values ​​/ dimension.xml à partir du code source

337

Je voudrais charger la valeur telle qu'elle est. J'ai deux dimension.xmlfichiers, l'un dedans /res/values/dimension.xmlet l'autre dedans /res/values-sw360dp/dimension.xml.

A partir du code source, je voudrais faire quelque chose comme

getResources().getDimension(R.dimen.tutorial_cross_marginTop);

Cela fonctionne mais la valeur que j'obtiens est multipliée par le facteur de densité d'écran (1,5 pour hdpi, 2,0 pour xhdpi, etc.).

J'ai aussi essayé de faire

getResources().getString(R.dimen.tutorial_cross_marginTop);

Cela fonctionnerait en principe mais j'obtiens une chaîne qui se termine par "dip" ...

Héctor Júdez Sapena
la source
1
Je me demande si c'est un bug dans Android car les ressources ont une méthode getDimensionPixelSize(int id)qui indique exactement qu'il retourne en Pixel, donc getDimension(int id)devrait retourner en dp (unités indépendantes de la dépendance), qui serait prêt à l'emploi, par exemple avec ViewsetPadding
Paul Verest

Réponses:

812

Dans mon dimens.xml j'ai

<dimen name="test">48dp</dimen>

Dans le code si je le fais

int valueInPixels = (int) getResources().getDimension(R.dimen.test)

cela retournera 72 qui, comme l'état des documents, est multiplié par la densité du téléphone actuel (48dp x 1,5 dans mon cas)

exactement comme le disent les documents:

Récupérez une dimension pour un ID de ressource particulier. Les conversions d'unités sont basées sur les DisplayMetrics actuels associés aux ressources.

donc si vous voulez une valeur dp exacte comme en xml, il suffit de la diviser avec la densité DisplayMetrics

int dp = (int) (getResources().getDimension(R.dimen.test) / getResources().getDisplayMetrics().density)

dp aura 48 ans maintenant

AndroidGecko
la source
3
Je pense que la documentation est particulièrement floue ici. "Les conversions d'unités sont basées sur les DisplayMetrics actuels associés aux ressources." quand tout ce qu'ils veulent dire, c'est qu'ils se convertissent en pixels.
Trilarion
Si vous allez essentiellement supprimer le multiplicateur de mesures d'affichage, vous pouvez tout aussi bien définir votre dimension en px. <dimen name = "test"> 48px </dimen>. getDimension (R.dimen.test) sera de retour 48.
Michael Peterson
Ne fonctionne pas pour moi: stackoverflow.com/questions/55972518/…
Alex
@Trilarion Cependant, ils ne se convertissent pas simplement en pixels. Ils disent que dpcela donnera la valeur de pixel mise à l'échelle par rapport à l'échelle de l'objet ressource utilisé pour le récupérer. Une fois que vous aurez trouvé diverses façons d'obtenir des ressources, ce sera plus pertinent. Pour simplifier, vous pouvez le considérer comme étant relatif à l'échelle de l'écran. Il y a aussi sp, ou pixels par rapport à la taille du texte du système, et px, ou pixels directement. Chacun est différent et a un but différent.
Panier abandonné du
20
Context.getResources().getDimension(int id);
Jug6ernaut
la source
18

La Resourceclasse a également une méthode getDimensionPixelSize () qui, je pense, répondra à vos besoins.

Ovidiu Latcu
la source
24
C'est faux! la conversion des mesures se produit également getDimensionPixelSize()si vous pouvez référencer les documents qu'elle indique clairement Retours Resource dimension value multiplied by the appropriate metric and truncated to integer pixels.
Muhammad Babar
C'est faux. La conversion des mesures s'effectue également à l'aide de cette méthode.
Michael Peterson
14

Pour ceux qui ont juste besoin d'économiser de la intvaleur dans les ressources, vous pouvez faire ce qui suit.

integers.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="default_value">100</integer>
</resources> 

Code

int defaultValue = getResources().getInteger(R.integer.default_value);
Suragch
la source
2
Merci pour cela, c'était plus ce que je cherchais même si peut-être pas pour d'autres, mais cette solution fournie m'a en fait donné un aperçu des autres domaines de mon code
JamisonMan111
11

Vous pouvez utiliser getDimensionPixelOffset () au lieu de getDimension, vous n'avez donc pas eu à transtyper en int.

int valueInPixels = getResources().getDimensionPixelOffset(R.dimen.test)
Jonny Right
la source
2
    This works but the value I get is multiplied times the screen density factor
  (1.5 for hdpi, 2.0 for xhdpi, etc).

Je pense qu'il est bon d'obtenir la valeur selon la résolution mais si vous ne voulez pas le faire, donnez ceci en px .......

Pixel indépendant de la densité (dp)

Unité de pixels virtuels que vous devez utiliser lors de la définition de la disposition de l'interface utilisateur pour exprimer les dimensions ou la position de la disposition de manière indépendante de la densité. Le pixel indépendant de la densité équivaut à un pixel physique sur un écran à 160 dpi, qui est la densité de base supposée par le système pour un écran à densité "moyenne". Au moment de l'exécution, le système gère de manière transparente toute mise à l'échelle des unités dp, si nécessaire. based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels.Vous devez toujours utiliser les unités dp lors de la définition de l'interface utilisateur de votre application, pour assurer un affichage correct de votre interface utilisateur sur des écrans de densités différentes.

Je pense qu'il est bon de changer la valeur selon la résolution mais si vous ne voulez pas le faire, donnez ceci en px .......

référer ce lien

selon cela

dp

Pixels indépendants de la densité - Unité abstraite basée sur la densité physique de l'écran. Ces unités sont relatives à un écran de 160 dpi (points par pouce), sur lequel 1dp est à peu près égal à 1px.When running on a higher density screen, the number of pixels used to draw 1dp is scaled up by a factor appropriate for the screen's dpi. Likewise, when on a lower density screen, the number of pixels used for 1dp is scaled down.Le rapport dp / pixel changera avec la densité de l'écran, mais pas nécessairement en proportion directe. L'utilisation d'unités dp (au lieu d'unités px) est une solution simple pour redimensionner correctement les dimensions de la vue dans votre mise en page pour différentes densités d'écran. En d'autres termes, il offre une cohérence pour les tailles réelles de vos éléments d'interface utilisateur sur différents appareils.

px

Pixels - Correspond aux pixels réels sur l'écran. Cette unité de mesure n'est pas recommandée car la représentation réelle peut varier d'un appareil à l'autre; chaque périphérique peut avoir un nombre différent de pixels par pouce et peut avoir plus ou moins de pixels totaux disponibles sur l'écran.

Dheeresh Singh
la source
2

Utiliser une extension Kotlin

Vous pouvez ajouter une extension pour simplifier ce processus. Il vous permet d'appeler simplement context.dp(R.dimen. tutorial_cross_marginTop)pour obtenir la valeur flottante

fun Context.px(@DimenRes dimen: Int): Int = resources.getDimension(dimen).toInt()

fun Context.dp(@DimenRes dimen: Int): Float = px(dimen) / resources.displayMetrics.density

Si vous souhaitez le gérer sans contexte, vous pouvez utiliser Resources.getSystem():

val Int.dp get() = this / Resources.getSystem().displayMetrics.density // Float

val Int.px get() = (this * Resources.getSystem().displayMetrics.density).toInt()

Par exemple, sur un périphérique xhdpi, utilisez 24.dppour obtenir 12,0 ou 12.pxobtenir 24

Gibolt
la source