Aggiungi valore in virgola mobile a risorse / valori Android


243

Sto cercando di aggiungere un po 'di spazio tra le righe alle mie TextViews utilizzando android:lineSpacingMultiplier dalla documentazione :

Spaziatura aggiuntiva tra le righe di testo, come moltiplicatore.

Deve essere un valore in virgola mobile, ad esempio "1.2".

Dato che lo sto usando in alcune diverse visualizzazioni di testo, vorrei aggiungere una dimensione / valore globale alle mie risorse, ma non so quale tag utilizzare, se esiste. Ho provato tutti i tipi di risorse che hanno senso per me, ma nessuno di loro funziona.

Quello che vorrei avere sarebbe qualcosa del genere:

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

Modifica: ne sono a conoscenza android:lineSpacingExtra(che necessita di una dimensione con un'unità aggiunta), ma mi piacerebbe usarlo android:lineSpacingMultiplierse possibile.

Risposte:


517

C'è una soluzione:

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

In questo modo, il tuo numero float sarà sotto @dimen. Si noti che è possibile utilizzare altri modificatori di "formato" e / o "tipo", dove formato sta per:

Formato = che racchiude il tipo di dati:

  • galleggiante
  • booleano
  • frazione
  • numero intero
  • ...

e tipo sta per:

Tipo = tipo di risorsa (referenziato con R.XXXXX.name):

  • colore
  • dimen
  • corda
  • stile
  • eccetera...

Per recuperare la risorsa dal codice, è necessario utilizzare questo frammento:

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

So che questo è confuso (ti aspetteresti una chiamata simile getResources().getDimension(R.dimen.text_line_spacing)), ma Android dimensionsha un trattamento speciale e il numero "float" puro non è una dimensione valida.


Inoltre, c'è un piccolo "hack" per mettere in dimensione il numero del float, ma ATTENZIONE che questo è davvero un hack , e stai rischiando di perdere la gamma e la precisione del float.

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

e dal codice, puoi ottenere quel float

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

in questo caso, il valore di lineSpacingè 2.024993896484375e non 2.025come ci si aspetterebbe.


2
Ho provato ad usare questo ma ottengo NotFoundException, "digitare # 0x04 non è valido", quando si recupera il valore dal codice.
Moises Jimenez,

puoi essere più specifico sul problema? probabilmente hai usato un tipo di dati errato per il formato ...
Tomo

19
@rodkarom per recuperare float da xml, utilizzare questo XML: <item type="string" format="float" name="my_float">0.5</item>e questo codice per recuperarlo:float my_float = Float.parseFloat (getResources ().getString (R.string.my_float));
gregn3

1
@ gregn3 Non è possibile farlo semplicemente con il <string>tag?
pablisco,

4
Penso che dovresti rimuovere la parte hackish, il sollution è semplicemente perfetto così com'è.
Mathijs Segers,


43

Tutte le soluzioni suggeriscono di utilizzare il valore float predefinito tramite il codice.

Ma nel caso ti stia chiedendo come fare riferimento al valore float predefinito in XML (ad esempio layout), il seguente è un esempio di ciò che ho fatto e funziona perfettamente:

Definire i valori delle risorse come type="integer"ma format="float", ad esempio:

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

E successivamente usali nel tuo layout usando @integer/name_of_resource, ad esempio:

<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
Questa è la risposta migliore perché mi consente di modificare dinamicamente i valori delle dimensioni durante la rotazione dello schermo senza dover scrivere codice.
Phileo99,

@Vyacheslav per i drawable, dovresti usare le dimensioni
waqaslam il

non funziona affatto. AndroidStudio fallisce anche con le dimensioni
Vyacheslav

Intendevo usare<dimen>
waqaslam il

19

Ho anche trovato una soluzione alternativa che sembra funzionare bene senza avvisi:

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

Poi:

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

Attenzione : funziona solo quando si utilizza il dimen dal codice Java e non da XML


Questo sfortunatamente non funziona, se uso tale valore nella definizione XML: android: lineSpacingMultiplier = "@ dimen / TEXT_SPACING_MULTIPLIER". Causa NumberFormatException mentre gonfia il layout.
peter.bartos,

4
Esattamente. Funziona solo quando si utilizza il dimen dal codice Java.
Cristian,

2
Questo è il modo migliore che ho trovato per accedere ai float dal codice.
Alex Lockwood,

In floats.xml ho aggiunto <item name = "shadow_percent" type = "dimen"> 25% </item> e poi nel mio disegno ho usato questa percentuale per impostare il centro del gradiente di ombra usando android: centerY = "@ dimen / shadow_percent ". Questo ha funzionato perfettamente per impostare l'ombra al 25% dell'altezza totale dell'elenco dei livelli. GRAZIE!
Chris Sprague,

solo una nota, dovresti usare type="fraction"per evitare errori nel codice Java
adek111

8

Aggiungi un float a dimens.xml:

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

Per fare riferimento da XML:

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

Per leggere questo valore a livello ResourcesCompat.getFloatdi codice è possibile utilizzare da androidx.core

Dipendenza dal grado:

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

Uso:

import androidx.core.content.res.ResourcesCompat;

...

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

7

Possiamo anche usarlo come linea guida per il layout dei vincoli.

Crea il file integer.xml e aggiungilo a

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

Utilizzare da un file layout.xml

 app:layout_constraintGuide_percent="@integer/guideline_button_top" 

1
esattamente quello di cui ho bisogno, lo uso per valori percentuali diversi per tablet e diversi per dispositivi mobili senza creare due file di layout
abdu

5

Ho usato uno stile per risolvere questo problema. Il link ufficiale è qui .

Roba abbastanza utile. Crea un file per contenere i tuoi stili (come "styles.xml") e definirli al suo interno. Quindi fai riferimento agli stili nel tuo layout (come "main.xml").

Ecco uno stile di esempio che fa quello che vuoi:

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

Supponiamo che tu voglia modificare un semplice TextView con questo. Nel tuo file di layout dovresti digitare:

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

Provalo: questo è essenzialmente il modo in cui tutta l'interfaccia utente integrata viene eseguita su Android. E usando gli stili, hai la possibilità di modificare ogni sorta di altri aspetti delle tue Viste.


2

Se hai float semplici di cui controlli l'intervallo, puoi anche avere un numero intero nelle risorse e dividerlo per il numero di posizioni decimali necessarie direttamente nel codice.

Quindi qualcosa del genere

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

viene utilizzato con 2 cifre decimali

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

e questo lo rende 3.56f

Non dire che questa è la soluzione più elegante ma per progetti semplici, è conveniente.


0

Ho trovato una soluzione, che funziona, ma risulta in un Warning( WARN/Resources(268): Converting to float: TypedValue{t=0x3/d=0x4d "1.2" a=2 r=0x7f06000a}) in LogCat.

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

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

vedi la mia risposta sopra. puoi utilizzare l'elemento di risorsa "generico", dove devi specificare il formato e il tipo. il formato è per il tipo java (float, booleano, frazione, numero intero, ecc.) e il tipo è per riferimento alla risorsa gen android ("dimen" per R.dimen, "color" per R.color, "string" per R.string , ecc.)
Tomo,

Questa è stata la mia risposta iniziale che ora è davvero superata, ecco perché ho accettato la tua risposta. :)
slup

0

Anche se ho usato la risposta accettata in passato, sembra che con gli attuali strumenti di costruzione sia possibile fare:

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

Sto usando Build Major versione 29.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.