Adicionar valor de ponto flutuante aos recursos / valores do Android

243

Estou tentando adicionar um pouco de espaço entre as linhas aos meus TextViews usando android:lineSpacingMultiplier a documentação :

Espaçamento extra entre linhas de texto, como um multiplicador.

Deve ser um valor de ponto flutuante, como "1,2".

Como estou usando isso em alguns TextViews diferentes, gostaria de adicionar uma dimensão / valor global aos meus recursos, mas não sei qual tag usar, se ela existir. Eu tentei todos os tipos de recursos que fazem sentido para mim, mas nenhum deles funciona.

O que eu gostaria de ter seria algo como isto:

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

Edit: Estou ciente de android:lineSpacingExtra(que precisa de uma dimensão com uma unidade anexada), mas eu gostaria de usar, android:lineSpacingMultiplierse possível.

slup
fonte

Respostas:

517

Existe uma solução:

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

Dessa forma, seu número flutuante estará abaixo de @dimen. Observe que você pode usar outros modificadores "formato" e / ou "tipo", em que formato significa:

Formato = tipo de dados anexado:

  • flutuador
  • boleano
  • fração
  • inteiro
  • ...

e type significa:

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

  • cor
  • escurecer
  • corda
  • estilo
  • etc ...

Para buscar recursos do código, você deve usar este trecho:

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

Eu sei que isso é confuso (você esperaria uma ligação getResources().getDimension(R.dimen.text_line_spacing)), mas o Android dimensionstem tratamento especial e o número "flutuante" puro não é uma dimensão válida.


Além disso, há um pequeno "hack" para colocar o número do flutuador em dimensão, mas lembre-se de que esse é realmente um hack e você está correndo o risco de perder o alcance e a precisão do flutuador.

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

e a partir do código, você pode obter esse float

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

nesse caso, o valor de lineSpacingé 2.024993896484375e não 2.025como o esperado.

Tomo
fonte
2
Tentei usar isso, mas obtive NotFoundException, "o tipo # 0x04 não é válido", ao recuperar o valor do código.
Moises Jimenez
você pode ser mais específico sobre o problema? Você provavelmente já usou tipo de dados errado para o formato ...
Tomo
19
@rodkarom para recuperar carros alegóricos de xml, usar este XML: <item type="string" format="float" name="my_float">0.5</item>e este código para recuperá-lo:float my_float = Float.parseFloat (getResources ().getString (R.string.my_float));
gregn3
1
@ gregn3 Isso não poderia ser feito simplesmente com a <string>tag?
pablisco
4
Eu acho que você deve remover a parte hackish, a solução é perfeita como é.
Mathijs Segers
83

Conforme descrito neste link http://droidista.blogspot.in/2012/04/adding-float-value-to-your-resources.html

Declarar em dimen.xml

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

Referenciando xml

@dimen/my_float_value

Referenciando de java

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

Todas as soluções sugerem que você use o valor flutuante predefinido por meio do código.

Mas caso você esteja se perguntando como fazer referência ao valor flutuante predefinido em XML (por exemplo, layouts), a seguir é apresentado um exemplo do que fiz e está funcionando perfeitamente:

Defina os valores dos recursos como type="integer"mas format="float", por exemplo:

<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 depois use-os no seu layout usando @integer/name_of_resource, por exemplo:

<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
fonte
1
Essa é a melhor resposta, pois me permite alterar dinamicamente os valores das dimensões durante a rotação da tela sem precisar escrever código.
Phileo99
@Vyacheslav para drawables, você deve usar padrão dimensões
waqaslam
não funciona de todo. O AndroidStudio falha mesmo com as dimensões
Vyacheslav
Eu quis dizer usando<dimen>
waqaslam
19

Também encontrei uma solução alternativa que parece funcionar bem sem avisos:

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

Então:

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

Atenção : ele só funciona quando você usa o dimen do código Java e não do xml

Cristian
fonte
Infelizmente, isso não funciona, se eu usar esse valor na definição XML: android: lineSpacingMultiplier = "@ dimen / TEXT_SPACING_MULTIPLIER". Isso causa NumberFormatException ao inflar o layout.
Peter.bartos
4
Exatamente. Funciona apenas quando você usa o dimen do código Java.
Cristian
2
Esta é a melhor maneira que eu poderia encontrar para acessar carros alegóricos a partir do código.
Alex Lockwood
Em floats.xml, adicionei <item name = "shadow_percent" type = "dimen"> 25% </item> e, em meu drawable, usei esse percentual para definir o centro do gradiente de sombra usando o android: centerY = "@ dimen / shadow_percent " Isso funcionou perfeitamente para definir a sombra para 25% da altura total da lista de camadas. OBRIGADO!
Chris Sprague
apenas uma observação, você deve usar type="fraction"para evitar erros no código Java #
adek111
8

Adicione um float ao dimens.xml:

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

Para fazer referência a partir do XML:

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

Para ler esse valor programaticamente, você pode usar a ResourcesCompat.getFloatpartir androidx.core

Dependência 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
fonte
7

Também podemos usá-lo como orientação do layout de restrição.

Crie o arquivo integer.xml e inclua no

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

Use de um arquivo layout.xml

 app:layout_constraintGuide_percent="@integer/guideline_button_top" 
Photon Point
fonte
1
exatamente o que eu preciso, eu uso isso para diferentes valores percentuais para tablets e diferente para celular sem criar dois arquivos de layout
abdu
5

Eu usei um estilo para resolver esse problema. O link oficial está aqui .

Coisas bastante úteis. Você cria um arquivo para armazenar seus estilos (como "styles.xml") e os define dentro dele. Você então faz referência aos estilos no seu layout (como "main.xml").

Aqui está um estilo de amostra que faz o que você deseja:

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

Digamos que você queira alterar um TextView simples com isso. No seu arquivo de layout, você digitaria:

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

Experimente - é essencialmente assim que toda a interface do usuário é feita no Android. E, usando estilos, você tem a opção de modificar todos os tipos de outros aspectos de suas visualizações também.

Scott Biggs
fonte
2

Se você possui flutuadores simples dos quais controla o intervalo, também pode ter um número inteiro nos recursos e dividir pelo número de casas decimais necessárias no código.

Então, algo assim

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

é usado com 2 casas decimais

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

e isso torna 3.56f

Não dizendo que esta é a solução mais elegante, mas para projetos simples, é conveniente.

Thanasis Kapelonis
fonte
0

Eu encontrei uma solução, que funciona, mas resulta em um Warning( WARN/Resources(268): Converting to float: TypedValue{t=0x3/d=0x4d "1.2" a=2 r=0x7f06000a}) no LogCat.

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

<android:lineSpacingMultiplier="@string/text_line_spacing"/>
slup
fonte
veja minha resposta acima. você pode usar o item de recurso "genérico", onde deve especificar o formato e o tipo. formato é para o tipo java (float, booleano, fração, número inteiro etc.) e type é para referência de recurso de geração do Android ("dimen" para R.dimen, "color" para R.color, "string" para R.string , etc)
Tomo
Esta foi a minha resposta inicial, que está realmente desatualizada agora, é por isso que aceitei sua resposta. :)
slup
0

Embora eu tenha usado a resposta aceita no passado, parece que com as ferramentas de compilação atuais é possível:

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

Estou usando a versão principal do Build Tools 29.

androidguy
fonte