Załaduj wartość wymiaru z res / wartości / wymiar.xml z kodu źródłowego

337

Chciałbym załadować wartość taką, jaka jest. Mam dwa dimension.xmlpliki, jeden w, /res/values/dimension.xmla drugi w /res/values-sw360dp/dimension.xml.

Z kodu źródłowego chciałbym zrobić coś takiego

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

To działa, ale wartość, którą otrzymuję, jest mnożona przez współczynnik gęstości ekranu (1,5 dla hdpi, 2,0 dla xhdpi itp.).

Próbowałem też to zrobić

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

Działa to w zasadzie, ale otrzymuję ciąg znaków, który kończy się na „zanurzeniu” ...

Héctor Júdez Sapena
źródło
1
Zastanawiam się, czy jest to błąd w Androidzie, ponieważ Resources ma metodę, getDimensionPixelSize(int id)która dokładnie stwierdza, że ​​zwraca w pikselach, więc getDimension(int id)powinien zwrócić w dp (jednostkach niezależnych od zależności), które byłyby gotowe do użycia, np. Z ViewsetPadding
Paul Verest

Odpowiedzi:

811

W moim dimens.xml mam

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

W kodzie, jeśli tak

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

to zwróci 72, które jako stan dokumentów są mnożone przez gęstość bieżącego telefonu (w moim przypadku 48dp x 1,5)

dokładnie tak, jak mówią dokumenty:

Pobierz wymiar dla określonego identyfikatora zasobu. Konwersje jednostek są oparte na bieżących DisplayMetrics powiązanych z zasobami.

więc jeśli chcesz dokładną wartość dp, podobnie jak w xml, po prostu podziel ją gęstością DisplayMetrics

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

dp będzie teraz 48

AndroidGecko
źródło
3
Myślę, że dokumentacja jest tutaj szczególnie niejasna. „Konwersje jednostek są oparte na bieżących DisplayMetrics powiązanych z zasobami”. kiedy chcą tylko powiedzieć, że konwertują na piksele.
Trilarion,
Jeśli zasadniczo chcesz odrzucić mnożnik wskaźników wyświetlania, równie dobrze możesz po prostu zdefiniować swój wymiar w px. <dimen name = "test"> 48px </dimen>. getDimension (R.dimen.test) zwróci 48.
Michael Peterson
Nie działa dla mnie: stackoverflow.com/questions/55972518/…
Alex
@Trilarion Nie konwertują jednak po prostu pikseli. Mówią, że dpda skalowaną wartość piksela w stosunku do skali obiektu zasobu użytego do jej odzyskania. Gdy znajdziesz różne sposoby pozyskiwania zasobów, będzie to bardziej odpowiednie. Dla uproszczenia można go traktować jako relatywny do skali ekranu. Występują również splub piksele w stosunku do wielkości tekstu systemowego i pxlub piksele bezpośrednio. Każdy jest inny i ma inny cel.
Opuszczony koszyk
20
Context.getResources().getDimension(int id);
Jug6ernaut
źródło
17

ResourceKlasa ma również metoda getDimensionPixelSize () , które myślę, że będzie pasować do Twoich potrzeb.

Ovidiu Latcu
źródło
24
To jest źle! konwersja metryk ma również miejsce, getDimensionPixelSize()jeśli można odwołać się do dokumentów, które wyraźnie stwierdza Zwraca Resource dimension value multiplied by the appropriate metric and truncated to integer pixels.
Muhammad Babar,
To jest źle. Konwersja metryk odbywa się również przy użyciu tej metody.
Michael Peterson
14

Dla tych, którzy chcą zaoszczędzić trochę intzasobów, możesz wykonać następujące czynności.

integers.xml

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

Kod

int defaultValue = getResources().getInteger(R.integer.default_value);
Suragch
źródło
2
Dziękuję za to, byłem więcej tego, czego szukałem, chociaż może nie dla innych, ale to rozwiązanie zapewniło mi wgląd w inne obszary mojego kodu
JamisonMan111,
11

Możesz użyć getDimensionPixelOffset () zamiast getDimension, więc nie musiałeś rzutować na int.

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

Myślę, że dobrze jest uzyskać wartość według rozdzielczości, ale jeśli nie chcesz tego zrobić, podaj to w px .......

Piksel niezależny od gęstości (dp)

Wirtualna jednostka pikseli, której należy używać podczas definiowania układu interfejsu użytkownika, w celu wyrażenia wymiarów lub położenia układu w sposób niezależny od gęstości. Piksel niezależny od gęstości odpowiada jednemu pikselowi fizycznemu na ekranie o rozdzielczości 160 dpi, który jest podstawową gęstością przyjętą przez system dla ekranu o „średniej” gęstości. W czasie wykonywania system w przejrzysty sposób obsługuje wszelkie skalowanie jednostek dp, w razie potrzeby. 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.Podczas definiowania interfejsu użytkownika aplikacji należy zawsze używać jednostek dp, aby zapewnić prawidłowe wyświetlanie interfejsu użytkownika na ekranach o różnej gęstości.

Myślę, że warto zmienić wartość zgodnie z rozdzielczością, ale jeśli nie chcesz tego zrobić, podaj to w px .......

sprawdź ten link

zgodnie z tym

dp

Piksele niezależne od gęstości - jednostka abstrakcyjna oparta na fizycznej gęstości ekranu. Jednostki te odnoszą się do ekranu o rozdzielczości 160 dpi (punktów na cal), na którym 1dp jest z grubsza równy 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.Stosunek dp-do piksela zmienia się wraz z gęstością ekranu, ale niekoniecznie w proporcji bezpośredniej. Korzystanie z jednostek dp (zamiast jednostek px) jest prostym rozwiązaniem, aby odpowiednio zmienić wymiary widoku w układzie dla różnych gęstości ekranu. Innymi słowy, zapewnia spójność rzeczywistych rozmiarów elementów interfejsu użytkownika na różnych urządzeniach.

px

Piksele - odpowiada rzeczywistym pikselom na ekranie. Ta jednostka miary nie jest zalecana, ponieważ rzeczywista reprezentacja może się różnić w zależności od urządzenia; każde urządzenie może mieć inną liczbę pikseli na cal i może mieć większą lub mniejszą liczbę pikseli dostępnych na ekranie.

Dheeresh Singh
źródło
2

Użyj rozszerzenia Kotlin

Możesz dodać rozszerzenie, aby uprościć ten proces. To pozwala tylko zadzwonić, context.dp(R.dimen. tutorial_cross_marginTop)aby uzyskać wartość Float

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

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

Jeśli chcesz obsłużyć go bez kontekstu, możesz użyć Resources.getSystem():

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

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

Na przykład na urządzeniu xhdpi użyj, 24.dpaby uzyskać 12.0 lub 12.px24

Gibolt
źródło