Добавить значение с плавающей запятой в ресурсы / значения Android

243

Я пытаюсь добавить немного пространства между строками в мои TextViews, используя android:lineSpacingMultiplier из документации :

Дополнительный интервал между строками текста, как множитель.

Должно быть значением с плавающей запятой, например, «1.2».

Поскольку я использую это в нескольких различных TextViews, я хотел бы добавить глобальное измерение / значение к моим ресурсам, но я не знаю, какой тег использовать, если он вообще существует. Я перепробовал все типы ресурсов, которые имеют для меня смысл, но ни один из них не работает.

То, что я хотел бы иметь, было бы что-то вроде этого:

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

Изменить: я знаю android:lineSpacingExtra(который требует измерения с добавленной единицей), но я хотел бы использовать, android:lineSpacingMultiplierесли это возможно.

Slup
источник

Ответы:

517

Есть решение:

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

Таким образом, ваш номер с плавающей точкой будет находиться под @dimen. Обратите внимание, что вы можете использовать другие модификаторы «format» и / или «type», где format означает:

Формат = вмещающий тип данных:

  • поплавок
  • логический
  • доля
  • целое число
  • ...

и тип означает:

Тип = тип ресурса (на который указывает R.XXXXX.name):

  • цвет
  • DIMEN
  • строка
  • стиль
  • и т.д...

Чтобы получить ресурс из кода, вы должны использовать этот фрагмент:

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

Я знаю, что это сбивает с толку (вы могли бы ожидать, что звонить, как getResources().getDimension(R.dimen.text_line_spacing)), но Android dimensionsимеют особый подход, и чистый «число с плавающей точкой» не является допустимым измерением.


Кроме того, существует небольшой «взлом» для помещения числа с плавающей точкой в ​​размерность, но имейте в виду, что это действительно взлом , и вы рискуете потерять диапазон и точность с плавающей точкой.

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

и из кода, вы можете получить этот плавающий по

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

в этом случае значение lineSpacingравно 2.024993896484375, а не 2.025как вы ожидаете.

Томо
источник
2
Я пытался использовать это, но получаю NotFoundException, "тип # 0x04 недопустим", при получении значения из кода.
Моизес Хименес
Вы можете быть более конкретным о проблеме? вы, вероятно, использовали неверный тип данных для формата ...
Tomo
19
@rodkarom для извлечения поплавков из xml, используйте этот XML: <item type="string" format="float" name="my_float">0.5</item>и этот код для его получения:float my_float = Float.parseFloat (getResources ().getString (R.string.my_float));
gregn3
1
@ gregn3 Разве это нельзя сделать просто с помощью <string>тега?
Паблиско
4
Я думаю, что вы должны удалить хакерскую часть, раствор просто идеален.
Матейс Сегерс
83

Как описано в этой ссылке http://droidista.blogspot.in/2012/04/adding-float-value-to-your-resources.html

Объявить в измерении .xml

<item name="my_float_value" type="dimen" format="float">9.52</item>

Ссылка из XML

@dimen/my_float_value

Ссылка из Java

TypedValue typedValue = new TypedValue();
getResources().getValue(R.dimen.my_float_value, typedValue, true);
float myFloatValue = typedValue.getFloat();
yajnesh
источник
43

Все решения предлагают вам использовать предопределенное значение с плавающей запятой через код.

Но если вам интересно, как ссылаться на предопределенное значение с плавающей точкой в ​​XML (например, макеты), то ниже приведен пример того, что я сделал, и он работает отлично:

Определите значения ресурсов как, type="integer"но format="float", например:

<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>

И позже используйте их в вашем макете, используя @integer/name_of_resource, например:

<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>
waqaslam
источник
1
Это лучший ответ, потому что он позволяет мне динамически изменять значения измерений при повороте экрана без необходимости писать код.
Phileo99
@ Вячеслав для рисования, вы должны использовать стандартные размеры
waqaslam
это не работает вообще. AndroidStudio дает сбой даже с размерами
Вячеслав
Я имел в виду использование<dimen>
waqaslam
19

Я также нашел обходной путь, который, кажется, работает нормально без предупреждений:

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

Затем:

// 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);

Предупреждение : это работает только когда вы используете измерение из кода Java, а не из XML

Cristian
источник
Это, к сожалению, не работает, если я использую такое значение в определении XML: android: lineSpacingMultiplier = "@ dimension / TEXT_SPACING_MULTIPLIER". Это вызывает NumberFormatException при накачке макета.
peter.bartos
4
Именно. Это работает только тогда, когда вы используете измерение из кода Java.
Кристиан
2
Это лучший способ получить доступ к плавающим элементам из кода.
Алекс Локвуд
В floats.xml я добавил <item name = "shadow_percent" type = "dimension"> 25% </ item>, а затем в своем рисовании я использовал этот процент, чтобы установить центр градиента тени с помощью android: centerY = "@ dimension / shadow_percent ». Это отлично работало, чтобы установить тень на 25% от общей высоты списка слоев. СПАСИБО!
Крис Спраг
просто примечание, вы должны использовать, type="fraction"чтобы избежать ошибок в коде Java
adek111
8

Добавьте число с плавающей точкой в ​​dimensions.xml:

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

Для ссылки из XML:

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

Чтобы прочитать это значение программно вы можете использовать ResourcesCompat.getFloatиз androidx.core

Gradle зависимость:

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

Использование:

import androidx.core.content.res.ResourcesCompat;

...

float value = ResourcesCompat.getFloat(context.getResources(), R.dimen.my_dimen);
Алекс Бейкер
источник
7

Мы также можем использовать его как ориентир для схемы ограничений.

Создать файл integer.xml и добавить в

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

Использовать из файла layout.xml

 app:layout_constraintGuide_percent="@integer/guideline_button_top" 
Фотон Поинт
источник
1
именно то, что мне нужно, я использую это для разных процентных значений для планшетов и разных для мобильных устройств без создания двух файлов макета
abdu
5

Я использовал стиль, чтобы решить эту проблему. Официальная ссылка здесь .

Довольно полезный материал. Вы создаете файл для хранения ваших стилей (например, "styles.xml") и определяете их внутри него. Затем вы ссылаетесь на стили в вашем макете (например, "main.xml").

Вот пример стиля, который делает то, что вы хотите:

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

Допустим, вы хотите изменить простое TextView с этим. В вашем файле макета вы наберете:

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

Попробуйте - это, по сути, как все встроенный пользовательский интерфейс делается на Android. А с помощью стилей у вас есть возможность изменить все виды других аспектов ваших видов.

Скотт Биггс
источник
2

Если у вас есть простые числа с плавающей точкой, которыми вы управляете, вы также можете иметь целое число в ресурсах и делить его на количество десятичных знаков, которое вам нужно прямо в коде.

Так как то так

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

используется с 2 знаками после запятой

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

и это делает 3.56f

Не сказать, что это самое элегантное решение, но для простых проектов это удобно.

Танасис Капелонис
источник
0

Я нашел решение, которое работает, но приводит к Warning( WARN/Resources(268): Converting to float: TypedValue{t=0x3/d=0x4d "1.2" a=2 r=0x7f06000a}) в LogCat.

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

<android:lineSpacingMultiplier="@string/text_line_spacing"/>
Slup
источник
см. мой ответ выше. Вы можете использовать «универсальный» ресурс, где вы должны указать формат и тип. формат для типа Java (float, логическое, дробное, целое и т. д.), а тип для ссылки на ресурсы android gen («измерение» для R.dimen, «цвет» для R.color, «строка» для R.string и т. д.)
Tomo
Это был мой первоначальный ответ, который сейчас действительно устарел, поэтому я принял ваш ответ. :)
slup
0

Хотя я использовал принятый ответ в прошлом, кажется, что с текущими инструментами сборки это можно сделать:

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

Я использую Build Tools, основная версия 29.

androidguy
источник