Android và cài đặt chiều rộng và chiều cao theo chương trình theo đơn vị dp


304

Tôi đang làm:

button.setLayoutParams(new GridView.LayoutParams(65, 65));

Theo các tài liệu, các đơn vị cho chiều rộng và chiều cao (cả 65 ở trên) là "pixel". Làm thế nào để bạn buộc đây là pixel độc lập với thiết bị hoặc "dp"?

Câu trả lời:


541

Bạn sẽ phải chuyển đổi nó từ dps sang pixel bằng hệ số tỷ lệ hiển thị.

final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);

111
Chuyển đổi chính xác là (int) (dps * scale + 0,5f). Đây là công thức chúng tôi sử dụng trong suốt khuôn khổ.
Romain Guy

8
Công thức là trong các tài liệu. Để đọc thêm, hãy đi tới phần 3 của developer.android.com/guide/practices/
Kẻ

34
@RomainGuy, bạn có thể vui lòng thêm chức năng tiện ích vào API để chuyển đổi từ dpsang pxkhông? Cảm ơn.
AlikElzin-kilaka

3
Dps ở đây là gì? tôi nhận được lỗi "dps không thể được giải quyết thành một biến"? Những loại "dps" cần khai báo ??
Deepak

5
Biến "dps" là giá trị đầu vào mà bạn muốn chuyển đổi.
Robby Pond

233

Tôi biết đây là một câu hỏi cũ tuy nhiên tôi đã tìm thấy một cách gọn gàng hơn để thực hiện việc chuyển đổi này.

Java

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65, getResources().getDisplayMetrics());

Kotlin

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65f, resources.displayMetrics)

8
Cũng được thực hiện để tìm hiểu làm thế nào để làm điều này. Tôi không phải là người thích lặp lại công thức ở một vài nơi! Cảm ơn.
darrenp

2
Nếu không, hãy tạo hàm với công thức
Sayka

1
@Kenobi Nó thực hiện chuyển đổi cho bạn từ DP sang PX. Các65 là giá trị DP bạn muốn chuyển đổi thành PX
drspaceboo

7
Đây phải là câu trả lời được chấp nhận, không phải là câu trả lời hiện tại nơi những con số (0,5) này đến một cách kỳ diệu từ đâu
Johny19

1
@ Johny19 0,5 không phải là phép thuật. Đó chỉ là cách làm tròn số dấu phẩy động sang số nguyên gần nhất thay vì cắt bớt nó. Xem nhận xét của tôi về câu trả lời của Robby Pond để biết thêm chi tiết.
MarredCheese

38

Nhìn vào yêu cầu của bạn, có giải pháp thay thế là tốt. Có vẻ như bạn biết các kích thước trong dp tại thời gian biên dịch, vì vậy bạn có thể thêm một mục làm mờ trong tài nguyên. Sau đó, bạn có thể truy vấn mục nhập mờ và nó sẽ được tự động chuyển đổi thành pixel trong cuộc gọi này:

final float inPixels= mActivity.getResources().getDimension(R.dimen.dimen_entry_in_dp);

Và dimens.xml của bạn sẽ có:

<dimen name="dimen_entry_in_dp">72dp</dimen>

Mở rộng ý tưởng này, bạn chỉ cần lưu trữ giá trị 1dp hoặc 1sp dưới dạng mục nhập làm mờ và truy vấn giá trị và sử dụng nó làm số nhân. Sử dụng phương pháp này, bạn sẽ cách ly mã từ các công cụ toán học và dựa vào thư viện để thực hiện các phép tính.


Lưu ý rằng giá trị trả về thực sự là một int, vì vậy nó được chuyển thành float.
CorayThan

Đây là một câu trả lời tồi bởi vì đó là giá vé để năng động
Johny19

37

cách đơn giản nhất (và thậm chí hoạt động từ api 1) đã được thử nghiệm là:

getResources().getDimensionPixelSize(R.dimen.example_dimen);

Từ tài liệu:

Lấy một chiều cho một ID tài nguyên cụ thể để sử dụng làm kích thước trong các pixel thô. Điều này giống như getDimension (int), ngoại trừ giá trị được trả về được chuyển đổi thành pixel nguyên để sử dụng làm kích thước. Chuyển đổi kích thước bao gồm làm tròn giá trị cơ sở và đảm bảo rằng giá trị cơ sở khác không có ít nhất một pixel có kích thước.

Có, nó làm tròn giá trị nhưng nó không tệ lắm (chỉ trong các giá trị lẻ trên các thiết bị hdpi và ldpi cần thêm một giá trị nhỏ khi ldpi không phổ biến lắm) Tôi đã thử nghiệm trong một thiết bị xxhdpi chuyển đổi 4dp thành 16 (pixel) và đó là thật.

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.