Android dan mengatur lebar dan tinggi secara terprogram dalam satuan dp


304

Aku melakukan:

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

Menurut dokumen, satuan untuk lebar dan tinggi (keduanya 65 di atas) adalah "piksel". Bagaimana Anda memaksakan ini menjadi piksel independen perangkat, atau "dp"?

Jawaban:


541

Anda harus mengonversinya dari dps ke piksel menggunakan faktor skala tampilan.

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

111
Konversi yang benar adalah (int) (skala dps * + 0,5f). Ini adalah formula yang kami gunakan di seluruh kerangka kerja.
Romain Guy

8
Rumusnya ada dalam dokumen. Untuk bacaan lebih lanjut, buka bagian 3 dari developer.android.com/guide/practices/…
SK9

34
@ DomainGuy, bisakah Anda menambahkan fungsi utilitas ke API untuk mengkonversi dari dpke px? Terima kasih.
AlikElzin-kilaka

3
apa dps di sini? im mendapatkan "dps tidak dapat diselesaikan ke variabel" kesalahan? apa jenis "dps" perlu menyatakan ??
Deepak

5
Variabel "dps" adalah nilai input yang ingin Anda konversi.
Robby Pond

233

Saya tahu ini adalah pertanyaan lama namun saya telah menemukan cara yang jauh lebih rapi dalam melakukan konversi ini.

Jawa

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

Kotlin

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

8
Dilakukan dengan baik untuk mengetahui bagaimana melakukan ini. Saya bukan penggemar mengulangi formula di beberapa tempat! Terima kasih.
darrenp

2
Jika tidak, maka buat fungsi dengan rumus
Sayka

1
@ Kenobi Ini melakukan konversi untuk Anda dari DP ke PX. Di 65atas adalah nilai DP yang ingin Anda konversi ke PX
drspaceboo

7
Ini harus menjadi jawaban yang diterima, bukan yang sekarang di mana angka ini (0,5) datang secara ajaib dari mana
Johny19

1
@ Johny19 0,5 bukan sihir. Ini hanya bagaimana membulatkan angka floating point ke bilangan bulat terdekat daripada memotongnya. Lihat komentar saya pada jawaban Robby Pond untuk detail lebih lanjut.
MarredCheese

38

Melihat kebutuhan Anda, ada solusi alternatif juga. Tampaknya Anda tahu dimensi dalam dp pada waktu kompilasi, sehingga Anda dapat menambahkan entri dimen di sumber daya. Kemudian Anda dapat meminta entri dimen dan itu akan secara otomatis dikonversi ke piksel dalam panggilan ini:

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

Dan dimens.xml Anda akan memiliki:

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

Memperluas ide ini, Anda cukup menyimpan nilai 1dp atau 1sp sebagai entri dimen dan kueri nilai dan menggunakannya sebagai pengganda. Dengan menggunakan pendekatan ini, Anda akan mengisolasi kode dari hal-hal matematika dan bergantung pada perpustakaan untuk melakukan perhitungan.


Perhatikan bahwa nilai kembali sebenarnya adalah int, sehingga akan dilemparkan ke float.
CorayThan

Ini adalah jawaban yang buruk karena itu adalah tarif menjadi dinamis
Johny19

37

Cara paling sederhana (dan bahkan bekerja dari api 1) yang diuji adalah:

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

Dari dokumentasi:

Ambil dimensi untuk ID sumber daya tertentu untuk digunakan sebagai ukuran dalam piksel mentah. Ini sama dengan getDimension (int), kecuali nilai yang dikembalikan dikonversi ke piksel integer untuk digunakan sebagai ukuran. Konversi ukuran melibatkan pembulatan nilai dasar, dan memastikan bahwa nilai dasar yang tidak nol setidaknya berukuran satu piksel.

Ya itu pembulatan nilainya tetapi tidak terlalu buruk (hanya dalam nilai aneh pada perangkat hdpi dan ldpi perlu menambahkan sedikit nilai ketika ldpi tidak terlalu umum) Saya menguji dalam perangkat xxhdpi yang mengubah 4dp menjadi 16 (piksel) dan itu adalah benar.

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.