Android ve genişlik ve yüksekliği dp birimlerinde programlı olarak ayarlama


304

Yapıyorum:

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

Dokümanlara göre, genişlik ve yükseklik birimleri (her ikisi de yukarıdaki 65) "piksel" dir. Bunu aygıttan bağımsız pikseller veya "dp" olmaya nasıl zorlarsınız?

Yanıtlar:


541

Görüntü ölçeği faktörünü kullanarak dps'den piksele dönüştürmeniz gerekir.

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

111
Doğru dönüşüm (int) (dps * ölçeği + 0.5f) şeklindedir. Bu, çerçeve boyunca kullandığımız formüldür.
Romain Guy

8
Formül dokümanlar içindedir. Daha fazla okumak için developer.android.com/guide/practices/…
9'a

34
@RomainGuy, API'ya dönüştürmek için bir yardımcı program işlevi ekleyebilir dpmisiniz px? Teşekkürler.
AlikElzin-kilaka

3
burada dps nedir? im "dps değişken çözülemez" hatası alıyorum? ne tür "dps" beyan gerekir ??
Deepak

5
"Dps" değişkeni dönüştürmek istediğiniz giriş değeridir.
Robby Pond

233

Biliyorum bu eski bir soru ama ben bu dönüşümü yapmanın çok daha düzgün bir yolunu buldum.

Java

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

Kotlin

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

8
Bunu nasıl yapacağınızı öğrenmek için çok iyi. Birkaç yerde formül tekrarlama hayranı değilim! Teşekkürler.
darrenp

2
Değilse, formülle işlev oluşturun
Sayka

1
@Kenobi Sizin için DP'den PX'e dönüşüm yapar. 65Yukarıdaki PX dönüştürülür istediğiniz DP değerdir
drspaceboo

7
Bu, bu sayının (0.5) sihirli bir şekilde hiçbir yerden gelmediği geçerli cevap değil, kabul edilen cevap olmalıdır
Johny19

1
@ Johny19 0.5 sihir değil. Kayan noktalı bir sayıyı kısaltmak yerine en yakın tam sayıya yuvarlamak. Daha fazla ayrıntı için Robby Pond'un cevabı hakkındaki yorumuma bakın.
MarredCheese

38

İhtiyacınıza baktığımızda alternatif bir çözüm de var. Derleme zamanında dp'deki boyutları biliyorsunuz, böylece kaynaklara bir dimen girişi ekleyebilirsiniz. Daha sonra, dimen girişini sorgulayabilirsiniz ve bu çağrıda otomatik olarak piksele dönüştürülür:

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

Ve dimens.xml dosyasında şunlar bulunur:

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

Bu fikri genişleterek, 1dp veya 1sp değerini bir dimen girişi olarak saklayabilir ve değeri sorgulayabilir ve bir çarpan olarak kullanabilirsiniz. Bu yaklaşımı kullanarak, kodu matematik öğelerinden yalıtacak ve hesaplamaları yapmak için kütüphaneye güveneceksiniz.


Dönüş değerinin aslında bir int olduğunu unutmayın, bu nedenle bir kayan noktaya yayınlanır.
CorayThan

Dinamik olmak için ücret olduğu için bu kötü bir cevap
Johny19

37

Test edilen en basit yol (ve api 1'den bile çalışır):

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

Belgelerden:

Ham piksellerde boyut olarak kullanılmak üzere belirli bir kaynak kimliği için bir boyut alın. GetDimension (int) ile aynıdır, ancak döndürülen değer boyut olarak kullanmak için tamsayı piksele dönüştürülür. Bir boyut dönüşümü, taban değerinin yuvarlanmasını ve sıfır olmayan bir taban değerinin en az bir piksel boyutunda olmasını sağlar.

Evet değeri yuvarlıyor ama çok kötü değil (sadece hdpi ve ldpi cihazlarındaki tek değerlerde ldpi çok yaygın olmadığında biraz değer katmak gerekiyor) 4dp'yi 16'ya (piksel) dönüştüren bir xxhdpi cihazında test ettim ve doğru.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.