Tambahkan nilai floating point ke sumber daya / nilai android


243

Saya mencoba menambahkan sedikit ruang di antara baris ke TextViews saya menggunakan android:lineSpacingMultiplier dari dokumentasi :

Spasi ekstra antara baris teks, sebagai pengganda.

Harus berupa nilai floating point, seperti "1.2".

Karena saya menggunakan ini di beberapa TextViews yang berbeda, saya ingin menambahkan dimensi / nilai global ke sumber daya saya, tetapi saya tidak tahu tag mana yang digunakan, jika itu ada. Saya telah mencoba semua jenis sumber daya yang masuk akal bagi saya, tetapi tidak ada yang berfungsi.

Yang ingin saya miliki adalah sesuatu seperti ini:

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

Sunting: Saya sadar android:lineSpacingExtra(yang membutuhkan dimensi dengan unit yang ditambahkan), tetapi saya ingin menggunakannya android:lineSpacingMultiplierjika memungkinkan.

Jawaban:


517

Ada solusinya:

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

Dengan cara ini, nomor float Anda akan berada di bawah @dimen. Perhatikan bahwa Anda dapat menggunakan pengubah "format" dan / atau "tipe" lainnya, yang merupakan singkatan dari:

Format = melampirkan tipe data:

  • mengapung
  • boolean
  • pecahan
  • bilangan bulat
  • ...

dan jenis singkatan:

Jenis = jenis sumber daya (direferensikan dengan R.XXXXX.name):

  • warna
  • dimen
  • tali
  • gaya
  • dll ...

Untuk mengambil sumber daya dari kode, Anda harus menggunakan potongan ini:

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

Saya tahu ini membingungkan (Anda akan mengharapkan panggilan seperti getResources().getDimension(R.dimen.text_line_spacing)), tetapi Android dimensionsmemiliki perlakuan khusus dan angka "float" murni bukan dimensi yang valid.


Selain itu, ada "retasan" kecil untuk memasukkan angka float ke dalam dimensi, tetapi PERINGATAN bahwa ini benar - benar retas , dan Anda berisiko kehilangan peluang dan presisi float.

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

dan dari kode, Anda bisa mendapatkannya

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

dalam hal ini, nilai lineSpacingis 2.024993896484375, dan tidak 2.025seperti yang Anda harapkan.


2
Saya mencoba menggunakan ini tetapi mendapatkan NotFoundException, "ketik # 0x04 tidak valid", ketika mengambil nilai dari kode.
Moises Jimenez

dapatkah Anda lebih spesifik tentang masalah? Anda mungkin menggunakan tipe data yang salah untuk format ...
Tomo

19
@rodkarom untuk mengambil float dari xml, gunakan XML ini: <item type="string" format="float" name="my_float">0.5</item>dan kode ini untuk mengambilnya:float my_float = Float.parseFloat (getResources ().getString (R.string.my_float));
gregn3

1
@ gregn3 Tidak bisakah itu dilakukan hanya dengan <string>tag?
pablisco

4
Saya pikir Anda harus menghapus bagian hackish, solusi sempurna seperti itu.
Mathijs Segers


43

Semua solusi menyarankan Anda untuk menggunakan nilai float yang telah ditentukan melalui kode.

Tetapi jika Anda bertanya-tanya bagaimana referensi nilai float yang telah ditentukan dalam XML (misalnya tata letak), maka berikut ini adalah contoh dari apa yang saya lakukan dan itu bekerja dengan sempurna:

Tetapkan nilai sumber daya sebagai type="integer"tetapi format="float", misalnya:

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

Dan kemudian menggunakannya dalam tata letak Anda menggunakan @integer/name_of_resource, misalnya:

<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
Ini adalah jawaban terbaik karena memungkinkan saya untuk mengubah nilai dimensi dinamis pada rotasi layar tanpa harus menulis kode.
Phileo99

@Vyacheslav untuk drawables, Anda harus menggunakan dimensi
waqaslam

itu tidak bekerja sama sekali. AndroidStudio gagal bahkan dengan dimensi
Vyacheslav

Maksud saya menggunakan<dimen>
waqaslam

19

Saya juga menemukan solusi yang tampaknya berfungsi dengan baik tanpa peringatan:

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

Kemudian:

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

Peringatan : ini hanya berfungsi ketika Anda menggunakan dimen dari kode Java bukan dari xml


Sayangnya ini tidak berfungsi, jika saya menggunakan nilai seperti itu dalam definisi XML: android: lineSpacingMultiplier = "@ dimen / TEXT_SPACING_MULTIPLIER". Ini menyebabkan NumberFormatException saat menggembungkan tata letak.
peter.bartos

4
Persis. Ini hanya berfungsi ketika Anda menggunakan dimen dari kode Java.
Cristian

2
Ini adalah cara terbaik yang bisa saya temukan untuk mengakses float dari kode.
Alex Lockwood

Di floats.xml saya menambahkan <item name = "shadow_percent" type = "dimen"> 25% </item> dan kemudian di drawable saya, saya menggunakan persen ini untuk mengatur pusat gradien bayangan menggunakan android: centerY = "@ dimen / shadow_percent ". Ini berfungsi sempurna untuk mengatur bayangan ke 25% dari total tinggi daftar lapisan. TERIMA KASIH!
Chris Sprague

hanya sebuah catatan, Anda harus menggunakan type="fraction"untuk menghindari kesalahan dalam kode Java
adek111

8

Tambahkan float ke dimens.xml:

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

Untuk referensi dari XML:

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

Untuk membaca nilai ini secara terprogram Anda dapat menggunakan ResourcesCompat.getFloatdari androidx.core

Ketergantungan Gradle:

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

Pemakaian:

import androidx.core.content.res.ResourcesCompat;

...

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

7

Kita juga bisa menggunakannya untuk panduan tata letak kendala.

Buat file integer.xml dan tambahkan

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

Gunakan dari file layout.xml

 app:layout_constraintGuide_percent="@integer/guideline_button_top" 

1
persis apa yang saya butuhkan, saya menggunakan ini untuk nilai persen yang berbeda untuk tablet dan berbeda untuk seluler tanpa membuat dua file tata letak
abdu

5

Saya menggunakan gaya untuk mengatasi masalah ini. Tautan resmi ada di sini .

Hal yang cukup berguna. Anda membuat file untuk menahan gaya Anda (seperti "styles.xml"), dan mendefinisikannya di dalamnya. Anda kemudian mereferensikan gaya dalam tata letak Anda (seperti "main.xml").

Berikut ini contoh gaya yang melakukan apa yang Anda inginkan:

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

Katakanlah Anda ingin mengubah TextView sederhana dengan ini. Di file tata letak Anda, Anda akan mengetik:

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

Cobalah - ini pada dasarnya adalah bagaimana semua built-in UI dilakukan di android. Dan dengan menggunakan gaya, Anda memiliki opsi untuk memodifikasi segala macam aspek lain dari Tampilan Anda juga.


2

Jika Anda memiliki float sederhana yang mengontrol rentangnya, Anda juga dapat memiliki bilangan bulat dalam sumber daya dan membaginya dengan jumlah tempat desimal yang Anda perlukan langsung dalam kode.

Jadi sesuatu seperti ini

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

digunakan dengan 2 tempat desimal

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

dan itu membuatnya 3.56f

Tidak mengatakan ini adalah solusi yang paling elegan tetapi untuk proyek-proyek sederhana, lebih mudah.


0

Saya menemukan solusi, yang berfungsi, tetapi menghasilkan Warning( WARN/Resources(268): Converting to float: TypedValue{t=0x3/d=0x4d "1.2" a=2 r=0x7f06000a}) di LogCat.

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

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

lihat jawaban saya di atas. Anda dapat menggunakan item sumber daya "generik", di mana Anda harus menentukan format dan jenis. format untuk tipe java (float, boolean, fraction, integer, dll.), dan type adalah untuk referensi sumber daya android gen ("dimen" untuk R.dimen, "color" untuk R.color, "string" untuk R.string , dll.)
Tomo

Ini adalah jawaban awal saya yang benar-benar usang sekarang, itu sebabnya saya menerima jawaban Anda. :)
slup

0

Meskipun saya telah menggunakan jawaban yang diterima di masa lalu, sepertinya dengan Alat Bangun saat ini dimungkinkan untuk dilakukan:

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

Saya menggunakan Build Tools versi utama 29.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.