Dodaj wartość zmiennoprzecinkową do zasobów / wartości Androida


243

Próbuję dodać trochę miejsca między wierszami do moich TextView, używając android:lineSpacingMultiplier z dokumentacji :

Dodatkowe odstępy między wierszami tekstu jako mnożnik.

Musi być wartością zmiennoprzecinkową, na przykład „1.2”.

Ponieważ używam tego w kilku różnych TextViews, chciałbym dodać globalny wymiar / wartość do moich zasobów, ale nie wiem, którego znacznika użyć, jeśli w ogóle istnieje. Próbowałem wszystkich typów zasobów, które mają dla mnie sens, ale żaden z nich nie działa.

Chciałbym mieć coś takiego:

<resources>
    <dimen name="text_line_spacing">1.4</dimen>
</resources>

Edycja: Jestem świadomy android:lineSpacingExtra(który wymaga wymiaru z dołączoną jednostką), ale chciałbym użyć, android:lineSpacingMultiplierjeśli to możliwe.

Odpowiedzi:


517

Istnieje rozwiązanie:

<resources>
    <item name="text_line_spacing" format="float" type="dimen">1.0</item>
</resources>

W ten sposób Twój numer zmiennoprzecinkowy będzie pod @dimen. Zauważ, że możesz użyć innych modyfikatorów „format” i / lub „typ”, gdzie format oznacza:

Format = obejmujący typ danych:

  • pływak
  • boolean
  • frakcja
  • liczba całkowita
  • ...

i typ oznacza:

Type = typ zasobu (w odniesieniu do R.XXXXX.name):

  • kolor
  • dimen
  • strunowy
  • styl
  • itp...

Aby pobrać zasób z kodu, użyj tego fragmentu:

TypedValue outValue = new TypedValue();
getResources().getValue(R.dimen.text_line_spacing, outValue, true);
float value = outValue.getFloat();  

Wiem, że jest to mylące (można się spodziewać połączenia podobnego getResources().getDimension(R.dimen.text_line_spacing)), ale Android dimensionsma specjalne traktowanie i czysty numer „float” nie jest prawidłowym wymiarem.


Dodatkowo istnieje mały „hack”, aby umieścić liczbę zmiennoprzecinkową w wymiarze, ale OSTRZEŻENIE, że to naprawdę hack i ryzykujesz utratą zasięgu zmiennoprzecinkowego i precyzji.

<resources>
    <dimen name="text_line_spacing">2.025px</dimen>
</resources>

a z kodu można uzyskać to zmiennoprzecinkowe przez

float lineSpacing = getResources().getDimension(R.dimen.text_line_spacing);

w tym przypadku wartość lineSpacingjest 2.024993896484375, a nie 2.025tak, jak można się spodziewać.


2
Próbowałem tego użyć, ale otrzymałem NotFoundException „typ 0x04 nie jest prawidłowy” podczas pobierania wartości z kodu.
Moises Jimenez

czy możesz dokładniej określić problem? prawdopodobnie użyłeś niewłaściwego typu danych dla formatu ...
Tomo

19
@rodkarom, aby pobrać zmiennoprzecinkowe pliki z XML, użyj tego XML: <item type="string" format="float" name="my_float">0.5</item>i tego kodu, aby go pobrać:float my_float = Float.parseFloat (getResources ().getString (R.string.my_float));
gregn3 29.09.12

1
@ gregn3 Czy nie można tego zrobić po prostu za pomocą <string>tagu?
pablisco

4
Myślę, że powinieneś usunąć część hackish, sollution jest po prostu idealny.
Mathijs Segers,


43

Wszystkie rozwiązania sugerują użycie predefiniowanej wartości zmiennoprzecinkowej za pomocą kodu.

Ale jeśli zastanawiasz się, jak odwoływać się do predefiniowanej wartości zmiennoprzecinkowej w formacie XML (na przykład układy), poniżej znajduje się przykład tego, co zrobiłem i działa idealnie:

Zdefiniuj wartości zasobów jako, type="integer"ale format="float"na przykład:

<item name="windowWeightSum" type="integer" format="float">6.0</item>
<item name="windowNavPaneSum" type="integer" format="float">1.5</item>
<item name="windowContentPaneSum" type="integer" format="float">4.5</item>

A później użyj ich w swoim układzie, używając @integer/name_of_resourcena przykład:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="@integer/windowWeightSum"                 // float 6.0
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="@integer/windowNavPaneSum"        // float 1.5
        android:orientation="vertical">
        <!-- other views -->
    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="@integer/windowContentPaneSum"    // float 4.5
        android:orientation="vertical">
        <!-- other views -->
    </LinearLayout>

</LinearLayout>

1
To najlepsza odpowiedź, ponieważ pozwala mi dynamicznie zmieniać wartości wymiarów podczas obracania ekranu bez konieczności pisania kodu.
Phileo99,

@ Vyacheslav dla drawable, powinieneś użyć standardowych wymiarów
waqaslam,

to w ogóle nie działa. AndroidStudio kończy się niepowodzeniem nawet przy wymiarach
Wiaczesław,

Miałem na myśli użycie<dimen>
waqaslam,

19

Znalazłem też obejście, które wydaje się działać dobrze bez ostrzeżeń:

<resources>
    <item name="the_name" type="dimen">255%</item>
    <item name="another_name" type="dimen">15%</item>
</resources>

Następnie:

// theName = 2.55f
float theName = getResources().getFraction(R.dimen.the_name, 1, 1);
// anotherName = 0.15f
float anotherName = getResources().getFraction(R.dimen.another_name, 1, 1);

Ostrzeżenie : działa tylko wtedy, gdy używasz dimen z kodu Java, a nie z xml


To niestety nie działa, jeśli użyję takiej wartości w definicji XML: android: lineSpacingMultiplier = "@ dimen / TEXT_SPACING_MULTIPLIER". Powoduje wyjątek NumberFormatException podczas pompowania układu.
peter.bartos

4
Dokładnie. Działa tylko wtedy, gdy używasz dimen z kodu Java.
Cristian

2
To najlepszy sposób, w jaki mogłem znaleźć dostęp do liczb zmiennoprzecinkowych z kodu.
Alex Lockwood

W floats.xml dodałem <item name = "shadow_percent" type = "dimen"> 25% </item>, a następnie w moim rysunku użyłem tego procentu do ustawienia środka gradientu cienia za pomocą Androida: centerY = "@ dimen / shadow_percent „. Działa to doskonale, ustawiając cień na 25% całkowitej wysokości listy warstw. DZIĘKUJĘ CI!
Chris Sprague,

uwaga, należy użyć, type="fraction"aby uniknąć błędów w kodzie Java
adek111,

8

Dodaj liczbę zmiennoprzecinkową do dimens.xml:

<item format="float" name="my_dimen" type="dimen">1.2</item>

Aby odwołać się z XML:

<EditText 
    android:lineSpacingMultiplier="@dimen/my_dimen"
    ...

Aby odczytać tę wartość programowo, możesz użyć ResourcesCompat.getFloatz androidx.core

Zależność stopniowa:

implementation("androidx.core:core:${version}")

Stosowanie:

import androidx.core.content.res.ResourcesCompat;

...

float value = ResourcesCompat.getFloat(context.getResources(), R.dimen.my_dimen);

7

Możemy go również użyć do wytyczenia układu ograniczenia.

Utwórz plik integer.xml i dodaj do

 <item name="guideline_button_top" type="integer" format="float">0.60</item>

Użyj z pliku layout.xml

 app:layout_constraintGuide_percent="@integer/guideline_button_top" 

1
dokładnie tego, czego potrzebuję, używam tego do różnych wartości procentowych dla tabletów i różnych dla urządzeń mobilnych bez tworzenia dwóch plików układu
abdu

5

Użyłem stylu, aby rozwiązać ten problem. Oficjalny link jest tutaj .

Całkiem przydatne rzeczy. Tworzysz plik do przechowywania swoich stylów (np. „Styles.xml”) i definiujesz je w nim. Następnie odwołujesz się do stylów w swoim układzie (np. „Main.xml”).

Oto przykładowy styl, który robi to, co chcesz:

<style name="text_line_spacing">
   <item name="android:lineSpacingMultiplier">1.4</item>
</style>

Powiedzmy, że chcesz zmienić prosty TextView za pomocą tego. W pliku układu wpisz:

<TextView
   style="@style/summary_text"
   ...
   android:text="This sentence has 1.4 times more spacing than normal."
/>

Wypróbuj - jest to zasadniczo sposób, w jaki wszystkie wbudowane interfejsy użytkownika są wykonywane na Androidzie. Używając stylów, możesz zmodyfikować wszystkie inne aspekty swoich widoków.


2

Jeśli masz proste zmiennoprzecinkowe, których kontrolujesz zakres, możesz również mieć liczbę całkowitą w zasobach i podzielić przez liczbę miejsc dziesiętnych, których potrzebujesz prosto w kodzie.

Więc coś takiego

<integer name="strokeWidth">356</integer>

jest używany z 2 miejscami po przecinku

this.strokeWidthFromResources = resources_.getInteger(R.integer.strokeWidth);    
circleOptions.strokeWidth((float) strokeWidthFromResources/ 100);

i to czyni go 3.56f

To nie jest najbardziej eleganckie rozwiązanie, ale dla prostych projektów jest wygodne.


0

Znalazłem rozwiązanie, które działa, ale powoduje Warning( WARN/Resources(268): Converting to float: TypedValue{t=0x3/d=0x4d "1.2" a=2 r=0x7f06000a}) w LogCat.

<resources>
    <string name="text_line_spacing">1.2</string>
</resources>

<android:lineSpacingMultiplier="@string/text_line_spacing"/>

patrz moja odpowiedź powyżej. możesz użyć „ogólnego” elementu zasobu, w którym powinieneś określić format i typ. Format jest dla typu Java (zmiennoprzecinkowy, logiczny, ułamkowy, liczba całkowita itp.), a typ dla odwołania do zasobów genowych Androida („dimen” dla R.dimen, „color” dla R.color, „string” dla R.string , itp.)
Tomo

To była moja pierwotna odpowiedź, która jest teraz naprawdę nieaktualna, dlatego zaakceptowałem twoją odpowiedź. :)
slup

0

Chociaż w przeszłości korzystałem z akceptowanej odpowiedzi, wydaje się, że przy obecnych Narzędziach do kompilacji można:

   <dimen name="listAvatarWidthPercent">0.19</dimen>

Korzystam z głównych wersji Build Tools 29.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.