Laden Sie den Dimensionswert aus res / values ​​/ dimension.xml aus dem Quellcode

337

Ich möchte den Wert so laden, wie er ist. Ich habe zwei dimension.xmlDateien, eine in /res/values/dimension.xmlund die andere in /res/values-sw360dp/dimension.xml.

Aus dem Quellcode möchte ich so etwas machen

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

Dies funktioniert, aber der Wert, den ich erhalte, wird mit dem Bildschirmdichtefaktor multipliziert (1,5 für hdpi, 2,0 für xhdpi usw.).

Ich habe es auch versucht

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

Dies würde im Prinzip funktionieren, aber ich bekomme eine Zeichenfolge, die mit "dip" endet ...

Héctor Júdez Sapena
quelle
1
Ich frage mich, ob es ein Fehler in Android ist, da Resources eine Methode hat getDimensionPixelSize(int id), die genau angibt, dass es in Pixel zurückgegeben wird. getDimension(int id)Daher sollte es in dp (abhängigkeitsunabhängige Einheiten) zurückgegeben werden, das zur Verwendung bereit wäre, z. B. mit ViewsetPadding
Paul Verest,

Antworten:

811

In meiner dimension.xml habe ich

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

Im Code Wenn ich es tue

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

Dies gibt 72 zurück, was als Dokumentstatus mit der Dichte des aktuellen Telefons multipliziert wird (in meinem Fall 48dp x 1,5).

genau wie in den Dokumenten angegeben:

Rufen Sie eine Dimension für eine bestimmte Ressourcen-ID ab. Einheitenumrechnungen basieren auf der aktuellen DisplayMetrics, die den Ressourcen zugeordnet ist.

Wenn Sie also genau wie in XML einen exakten dp-Wert wünschen, teilen Sie ihn einfach mit der DisplayMetrics-Dichte

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

dp wird jetzt 48 sein

AndroidGecko
quelle
3
Ich denke, die Dokumentation ist hier besonders unklar. "Einheitenumrechnungen basieren auf der aktuellen DisplayMetrics, die den Ressourcen zugeordnet ist." wenn sie nur sagen wollen, dass sie in Pixel konvertieren.
Trilarion
Wenn Sie den Multiplikator für Anzeigemetriken im Wesentlichen verwerfen möchten, können Sie Ihre Dimension auch einfach in px definieren. <dimen name = "test"> 48px </ dimension>. getDimension (R.dimen.test) wird 48 zurückgeben.
Michael Peterson
Funktioniert nicht für mich: stackoverflow.com/questions/55972518/…
Alex
@Trilarion Sie konvertieren jedoch nicht einfach in Pixel. Sie sagen, dpdass dies den skalierten Pixelwert relativ zur Skalierung des Ressourcenobjekts ergibt, das zum Abrufen verwendet wird. Sobald Sie verschiedene Möglichkeiten gefunden haben, um Ressourcen zu erhalten, ist dies relevanter. Der Einfachheit halber können Sie sich das relativ zur Bildschirmskala vorstellen. Es gibt auch spoder Pixel relativ zur Systemtextgröße und pxoder oder Pixel direkt. Jeder ist anders und hat einen anderen Zweck.
Verlassener Wagen
20
Context.getResources().getDimension(int id);
Jug6ernaut
quelle
17

Die ResourceKlasse hat auch eine Methode getDimensionPixelSize (), die meiner Meinung nach Ihren Anforderungen entspricht.

Ovidiu Latcu
quelle
24
Das ist falsch! Die Metrikkonvertierung findet auch statt, getDimensionPixelSize()wenn Sie auf die Dokumente verweisen können, in denen eindeutig angegeben ist. Rückgabe Resource dimension value multiplied by the appropriate metric and truncated to integer pixels.
Muhammad Babar
Das ist falsch. Die Konvertierung der Metriken erfolgt ebenfalls mit dieser Methode.
Michael Peterson
14

Für diejenigen, die nur einen gewissen intWert in den Ressourcen sparen müssen , können Sie Folgendes tun.

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
quelle
2
Vielen Dank dafür, war mehr von dem, wonach ich gesucht habe, obwohl vielleicht nicht für andere, aber diese Lösung gab mir tatsächlich einen Einblick in andere Bereiche meines Codes
JamisonMan111
11

Sie können getDimensionPixelOffset () anstelle von getDimension verwenden, sodass Sie nicht in int umwandeln mussten.

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

Ich denke, es ist gut, den Wert gemäß Auflösung zu erhalten, aber wenn Sie dies nicht tun möchten, geben Sie dies in px an .......

Dichteunabhängiges Pixel (dp)

Eine virtuelle Pixeleinheit, die Sie beim Definieren des UI-Layouts verwenden sollten, um Layoutdimensionen oder -positionen dichteunabhängig auszudrücken. Das dichteunabhängige Pixel entspricht einem physikalischen Pixel auf einem 160-dpi-Bildschirm. Dies ist die Basisliniendichte, die vom System für einen Bildschirm mit "mittlerer" Dichte angenommen wird. Zur Laufzeit übernimmt das System bei Bedarf die Skalierung der dp-Einheiten transparent. 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.Sie sollten bei der Definition der Benutzeroberfläche Ihrer Anwendung immer dp-Einheiten verwenden, um eine ordnungsgemäße Anzeige Ihrer Benutzeroberfläche auf Bildschirmen mit unterschiedlichen Dichten sicherzustellen.

Ich denke, es ist gut, den Wert gemäß der Auflösung zu ändern, aber wenn Sie dies nicht tun möchten, geben Sie dies in px an .......

Verweisen Sie auf diesen Link

wie dies

dp

Dichteunabhängige Pixel - Eine abstrakte Einheit, die auf der physischen Dichte des Bildschirms basiert. Diese Einheiten beziehen sich auf einen Bildschirm mit 160 dpi (Punkte pro Zoll), auf dem 1 dp ungefähr 1px entspricht. 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.Das Verhältnis von dp zu Pixel ändert sich mit der Bildschirmdichte, jedoch nicht unbedingt in direktem Verhältnis. Die Verwendung von dp-Einheiten (anstelle von px-Einheiten) ist eine einfache Lösung, um die Größe der Ansichtsabmessungen in Ihrem Layout für unterschiedliche Bildschirmdichten richtig anzupassen. Mit anderen Worten, es bietet Konsistenz für die realen Größen Ihrer UI-Elemente auf verschiedenen Geräten.

px

Pixel - Entspricht den tatsächlichen Pixeln auf dem Bildschirm. Diese Maßeinheit wird nicht empfohlen, da die tatsächliche Darstellung von Gerät zu Gerät unterschiedlich sein kann. Jedes Gerät hat möglicherweise eine andere Anzahl von Pixeln pro Zoll und möglicherweise mehr oder weniger Gesamtpixel auf dem Bildschirm.

Dheeresh Singh
quelle
2

Verwenden Sie eine Kotlin-Erweiterung

Sie können eine Erweiterung hinzufügen, um diesen Vorgang zu vereinfachen. Sie können einfach aufrufen context.dp(R.dimen. tutorial_cross_marginTop), um den Float-Wert abzurufen

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

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

Wenn Sie ohne Kontext damit umgehen möchten, können Sie Folgendes verwenden Resources.getSystem():

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

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

Verwenden Sie beispielsweise auf einem xhdpi-Gerät, 24.dpum 12.0 oder 12.px24 abzurufen

Gibolt
quelle