Thêm giá trị dấu phẩy động vào tài nguyên / giá trị Android


243

Tôi đang cố gắng để thêm một chút không gian giữa các dòng để TextView của tôi sử dụng android:lineSpacingMultiplier từ các tài liệu :

Khoảng cách thêm giữa các dòng văn bản, như là một số nhân.

Phải là một giá trị dấu phẩy động, chẳng hạn như "1.2".

Vì tôi đang sử dụng điều này trong một vài TextView khác nhau, tôi muốn thêm thứ nguyên / giá trị toàn cầu vào tài nguyên của mình, nhưng tôi không biết nên sử dụng thẻ nào, nếu nó còn tồn tại. Tôi đã thử tất cả các loại tài nguyên có ý nghĩa với tôi, nhưng không có loại nào trong số chúng hoạt động.

Những gì tôi muốn có sẽ là một cái gì đó như thế này:

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

Chỉnh sửa: Tôi biết android:lineSpacingExtra(cần một thứ nguyên với đơn vị được nối thêm), nhưng tôi muốn sử dụng android:lineSpacingMultipliernếu có thể.

Câu trả lời:


517

Có một giải pháp:

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

Bằng cách này, số float của bạn sẽ ở dưới @dimen. Lưu ý rằng bạn có thể sử dụng các công cụ sửa đổi "định dạng" và / hoặc "loại" khác, trong đó định dạng là viết tắt của:

Định dạng = kèm theo kiểu dữ liệu:

  • Phao nổi
  • boolean
  • phân số
  • số nguyên
  • ...

và gõ là viết tắt của:

Loại = loại tài nguyên (được tham chiếu với R.XXXXX.name):

  • màu sắc
  • giảm bớt
  • chuỗi
  • Phong cách
  • Vân vân...

Để tìm nạp tài nguyên từ mã, bạn nên sử dụng đoạn mã này:

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

Tôi biết rằng điều này thật khó hiểu (bạn mong đợi cuộc gọi như thế nào getResources().getDimension(R.dimen.text_line_spacing)), nhưng Android dimensionscó cách xử lý đặc biệt và số "float" thuần túy không phải là thứ nguyên hợp lệ.


Ngoài ra, có một "hack" nhỏ để đưa số float vào kích thước, nhưng được CẢNH BÁO rằng đây thực sựhack và bạn có nguy cơ mất phạm vi và độ chính xác của float.

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

và từ mã, bạn có thể có được số float đó bằng cách

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

trong trường hợp này, giá trị của lineSpacing2.024993896484375, chứ không phải 2.025như bạn sẽ mong đợi.


2
Tôi đã thử sử dụng cái này nhưng nhận được NotFoundException, "loại # 0x04 không hợp lệ", khi lấy giá trị từ mã.
Moise Jimenez

bạn có thể cụ thể hơn về vấn đề? có lẽ bạn đã sử dụng sai loại dữ liệu cho định dạng ...
Tomo

19
@rodkarom để truy xuất số float từ xml, sử dụng XML này: <item type="string" format="float" name="my_float">0.5</item>và mã này để lấy nó:float my_float = Float.parseFloat (getResources ().getString (R.string.my_float));
gregn3

1
@ gregn3 Không thể thực hiện đơn giản với <string>thẻ?
pottaisco

4
Tôi nghĩ bạn nên loại bỏ phần hackish, sự hoàn hảo chỉ là hoàn hảo.
Mathijs Segers


43

Tất cả các giải pháp đề nghị bạn sử dụng giá trị float được xác định trước thông qua mã.

Nhưng trong trường hợp bạn đang tự hỏi làm thế nào để tham chiếu giá trị float được xác định trước trong XML (ví dụ như bố cục), thì sau đây là một ví dụ về những gì tôi đã làm và nó hoạt động hoàn hảo:

Xác định các giá trị tài nguyên như , type="integer"nhưng format="float", ví dụ:

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

Và sau này sử dụng chúng trong bố cục của bạn bằng cách sử dụng @integer/name_of_resource, ví dụ:

<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
Đây là câu trả lời tốt nhất vì nó cho phép tôi thay đổi giá trị kích thước động khi xoay màn hình mà không phải viết mã.
Phileo99

@Vyacheslav cho các ngăn kéo, bạn nên sử dụng kích thước
waqaslam

nó không hoạt động AndroidStudio thất bại ngay cả với các công cụ
Vyacheslav

Ý tôi là sử dụng<dimen>
waqaslam

19

Tôi cũng tìm thấy một cách giải quyết có vẻ hoạt động tốt mà không có cảnh báo:

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

Sau đó:

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

Cảnh báo : nó chỉ hoạt động khi bạn sử dụng dimen từ mã Java chứ không phải từ xml


Điều không may này không hoạt động, nếu tôi sử dụng giá trị như vậy trong định nghĩa XML: android: lineSpacesMultiplier = "@ dimen / TEXTinksACING_MULTIPLIER". Nó gây ra NumberFormatException trong khi bố trí tăng cao.
peter.bartos

4
Chính xác. Nó chỉ hoạt động khi bạn sử dụng dimen từ mã Java.
Cristian

2
Đây là cách tốt nhất tôi có thể tìm thấy để truy cập float từ mã.
Alex Lockwood

Trong floats.xml tôi đã thêm <item name = "Shadow_percent" type = "dimen"> 25% </ item> và sau đó trong drawable của tôi, tôi đã sử dụng phần trăm này để đặt trung tâm gradient của bóng bằng cách sử dụng android: centre = "@ dimen / Shadow_percent ". Điều này hoạt động hoàn hảo để đặt bóng tới 25% tổng chiều cao của danh sách lớp. CẢM ƠN BẠN!
Chris Sprague

chỉ là một lưu ý, bạn nên sử dụng type="fraction"để tránh lỗi trong mã Java
adek111

8

Thêm một float vào dimens.xml:

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

Để tham khảo từ XML:

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

Để đọc giá trị này theo chương trình, bạn có thể sử dụng ResourcesCompat.getFloattừ androidx.core

Phụ thuộc lớp:

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

Sử dụng:

import androidx.core.content.res.ResourcesCompat;

...

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

7

Chúng ta cũng có thể sử dụng nó cho hướng dẫn của bố cục ràng buộc.

Tạo tập tin số nguyên và thêm vào

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

Sử dụng từ tệp layout.xml

 app:layout_constraintGuide_percent="@integer/guideline_button_top" 

1
chính xác những gì tôi cần, tôi sử dụng giá trị này cho các giá trị phần trăm khác nhau cho máy tính bảng và khác nhau cho thiết bị di động mà không tạo hai tệp bố cục
abdu

5

Tôi đã sử dụng một phong cách để giải quyết vấn đề này. Các liên kết chính thức là ở đây .

Công cụ khá hữu ích. Bạn tạo một tệp để giữ các kiểu của bạn (như "style.xml") và xác định chúng bên trong nó. Sau đó, bạn tham chiếu các kiểu trong bố cục của mình (như "main.xml").

Đây là một kiểu mẫu thực hiện những gì bạn muốn:

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

Giả sử bạn muốn thay đổi một TextView đơn giản với điều này. Trong tệp bố cục của bạn, bạn nhập:

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

Hãy thử nó - đây thực chất là cách tất cả các UI tích hợp được thực hiện trên Android. Và bằng cách sử dụng các kiểu, bạn cũng có tùy chọn để sửa đổi tất cả các khía cạnh khác của Chế độ xem của mình.


2

Nếu bạn có các số float đơn giản mà bạn kiểm soát phạm vi, bạn cũng có thể có một số nguyên trong tài nguyên và chia cho số vị trí thập phân bạn cần thẳng trong mã.

Vì vậy, một cái gì đó như thế này

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

được sử dụng với 2 chữ số thập phân

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

và điều đó làm cho nó 3,56f

Không nói đây là giải pháp tao nhã nhất nhưng đối với các dự án đơn giản, thật tiện lợi.


0

Tôi đã tìm thấy một giải pháp, hoạt động, nhưng không dẫn đến một Warning( WARN/Resources(268): Converting to float: TypedValue{t=0x3/d=0x4d "1.2" a=2 r=0x7f06000a}) trong LogCat.

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

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

xem câu trả lời của tôi ở trên bạn có thể sử dụng mục tài nguyên "chung", trong đó bạn nên chỉ định định dạng và loại. định dạng dành cho loại java (float, boolean, phân số, số nguyên, v.v.) và loại dành cho tham chiếu tài nguyên gen android ("dimen" cho R.dimen, "color" cho R.color, "chuỗi" cho R. String , v.v.)
Tomo

Đây là câu trả lời ban đầu của tôi đã thực sự lỗi thời, đó là lý do tại sao tôi chấp nhận câu trả lời của bạn. :)
slup

0

Mặc dù trước đây tôi đã sử dụng câu trả lời được chấp nhận, nhưng có vẻ như với Công cụ xây dựng hiện tại có thể thực hiện:

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

Tôi đang sử dụng Build Tools phiên bản chính 29.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.