Agregar valor de punto flotante a los recursos / valores de Android

243

Estoy tratando de agregar un poco de espacio entre líneas a mis TextViews usando android:lineSpacingMultiplier la documentación :

Espaciado adicional entre líneas de texto, como multiplicador.

Debe ser un valor de coma flotante, como "1.2".

Como estoy usando esto en algunas TextViews diferentes, me gustaría agregar una dimensión / valor global a mis recursos, pero no sé qué etiqueta usar, si es que existe. He probado todos los tipos de recursos que tienen sentido para mí, pero ninguno de ellos funciona.

Lo que me gustaría tener sería algo como esto:

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

Editar: Soy consciente de android:lineSpacingExtra(que necesita una dimensión con una unidad adjunta), pero me gustaría usar android:lineSpacingMultipliersi es posible.

slup
fuente

Respuestas:

517

Hay una solucion:

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

De esta manera, su número de flotación estará debajo de @dimen. Tenga en cuenta que puede usar otros modificadores de "formato" y / o "tipo", donde el formato significa:

Formato = tipo de datos adjunto:

  • flotador
  • booleano
  • fracción
  • entero
  • ...

y el tipo significa:

Tipo = tipo de recurso (referenciado con R.XXXXX.name):

  • color
  • dimen
  • cuerda
  • estilo
  • etc ...

Para obtener recursos del código, debe usar este fragmento:

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

Sé que esto es confuso (esperarías llamar como getResources().getDimension(R.dimen.text_line_spacing)), pero Android dimensionstiene un tratamiento especial y el número "flotante" puro no es una dimensión válida.


Además, hay un pequeño "hack" para poner el número del flotador en dimensión, pero se ADVERTIDO que esto es realmente truco , y que están arriesgando la posibilidad de perder gama de flotación y precisión.

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

y del código, puedes obtener ese flotador

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

en este caso, el valor de lineSpacinges 2.024993896484375, y no 2.025como se esperaba.

Tomo
fuente
2
Intenté usar esto pero recibo NotFoundException, "el tipo # 0x04 no es válido", cuando recupero el valor del código.
Moisés Jiménez
¿Puedes ser más específico sobre el problema? Probablemente ha utilizado un tipo de datos incorrecto para el formato ...
Tomo
19
@rodkarom para recuperar flotantes de xml, use este XML: <item type="string" format="float" name="my_float">0.5</item>y este código para recuperarlo:float my_float = Float.parseFloat (getResources ().getString (R.string.my_float));
gregn3
1
@ gregn3 ¿No podría hacerse eso simplemente con la <string>etiqueta?
pablisco
44
Creo que deberías eliminar la parte pirata, la solución es simplemente perfecta.
Mathijs Segers
83

Como se describe en este enlace http://droidista.blogspot.in/2012/04/adding-float-value-to-your-resources.html

Declarar en dimen.xml

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

Referencias desde xml

@dimen/my_float_value

Referencias desde java

TypedValue typedValue = new TypedValue();
getResources().getValue(R.dimen.my_float_value, typedValue, true);
float myFloatValue = typedValue.getFloat();
yajnesh
fuente
43

Todas las soluciones sugieren que utilice el valor flotante predefinido a través del código.

Pero en caso de que se pregunte cómo hacer referencia al valor flotante predefinido en XML (por ejemplo, diseños), el siguiente es un ejemplo de lo que hice y funciona perfectamente:

Defina valores de recursos como type="integer"pero format="float", por ejemplo:

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

Y luego úselas en su diseño usando @integer/name_of_resource, por ejemplo:

<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
fuente
1
Esta es la mejor respuesta porque me permite cambiar dinámicamente los valores de dimensión al girar la pantalla sin tener que escribir código.
Phileo99
@Vyacheslav para sorteos, debe usar dimensiones
waqaslam
no funciona en absoluto. AndroidStudio falla incluso con dimensiones
Vyacheslav
Me refería a usar<dimen>
waqaslam
19

También encontré una solución alternativa que parece funcionar bien sin advertencias:

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

Luego:

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

Advertencia : solo funciona cuando usa el dimen del código Java no del xml

Cristian
fuente
Desafortunadamente, esto no funciona si uso dicho valor en la definición XML: android: lineSpacingMultiplier = "@ dimen / TEXT_SPACING_MULTIPLIER". Causa NumberFormatException al inflar el diseño.
peter.bartos
44
Exactamente. Solo funciona cuando usa el dimen del código Java.
Cristian
2
Esta es la mejor manera que pude encontrar para acceder a los flotantes desde el código.
Alex Lockwood
En floats.xml agregué <item name = "shadow_percent" type = "dimen"> 25% </item> y luego en mi dibujable usé este porcentaje para establecer el centro del gradiente de sombra usando android: centerY = "@ dimen / shadow_percent ". Esto funcionó perfectamente para establecer la sombra al 25% de la altura total de la lista de capas. ¡GRACIAS!
Chris Sprague
solo una nota, debe usar type="fraction"para evitar errores en el código Java
adek111
8

Agregue un flotador a dimens.xml:

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

Para hacer referencia desde XML:

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

Para leer este valor mediante programación, puede usarlo ResourcesCompat.getFloatdesde androidx.core

Dependencia de Gradle:

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

Uso:

import androidx.core.content.res.ResourcesCompat;

...

float value = ResourcesCompat.getFloat(context.getResources(), R.dimen.my_dimen);
Alex Baker
fuente
7

También podemos usarlo para la guía del diseño de restricción.

Cree el archivo integer.xml y agréguelo a

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

Usar desde un archivo layout.xml

 app:layout_constraintGuide_percent="@integer/guideline_button_top" 
Punto de fotones
fuente
1
exactamente lo que necesito, lo uso para diferentes valores de porcentaje para tabletas y diferentes para dispositivos móviles sin crear dos archivos de diseño
abdu el
5

Usé un estilo para resolver este problema. El enlace oficial está aquí .

Cosas bastante útiles. Usted crea un archivo para contener sus estilos (como "styles.xml") y los define dentro de él. Luego, hace referencia a los estilos en su diseño (como "main.xml").

Aquí hay un estilo de muestra que hace lo que quieres:

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

Digamos que desea alterar un TextView simple con esto. En su archivo de diseño escribiría:

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

Pruébalo: así es como se hace toda la interfaz de usuario integrada en Android. Y mediante el uso de estilos, también tiene la opción de modificar todo tipo de otros aspectos de sus Vistas.

Scott Biggs
fuente
2

Si tiene flotantes simples que controla el rango, también puede tener un número entero en los recursos y dividir por el número de decimales que necesita directamente en el código.

Entonces algo como esto

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

se usa con 2 decimales

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

y eso lo hace 3.56f

No digo que esta sea la solución más elegante, pero para proyectos simples, es conveniente.

Thanasis Kapelonis
fuente
0

Encontré una solución, que funciona, pero resulta en un Warning( WARN/Resources(268): Converting to float: TypedValue{t=0x3/d=0x4d "1.2" a=2 r=0x7f06000a}) en LogCat.

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

<android:lineSpacingMultiplier="@string/text_line_spacing"/>
slup
fuente
mira mi respuesta arriba. puede usar un elemento de recurso "genérico", donde debe especificar el formato y el tipo. el formato es para el tipo de Java (flotante, booleano, fracción, entero, etc.), y el tipo es para la referencia de recursos de Android gen ("dimen" para R.dimen, "color" para R.color, "string" para R.string , etc.)
Tomo
Esta fue mi respuesta inicial que ahora está realmente desactualizada, por eso acepté su respuesta. :)
slup
0

Aunque he usado la respuesta aceptada en el pasado, parece que con las herramientas de compilación actuales es posible hacerlo:

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

Estoy usando Build Tools versión principal 29.

androidguy
fuente