Android i programowe ustawianie szerokości i wysokości w jednostkach dp

304

Robię:

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

Według dokumentacji jednostkami szerokości i wysokości (obie powyżej 65) są „piksele”. Jak wymusić, aby były to piksele niezależne od urządzenia lub „dp”?

SK9
źródło

Odpowiedzi:

541

Będziesz musiał przekonwertować go z dps na piksele za pomocą współczynnika skali wyświetlania.

final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);
Robby Pond
źródło
111
Prawidłowa konwersja to (int) (skala dps * + 0,5f). To jest formuła, której używamy w ramach.
Romain Guy,
8
Formuła znajduje się w dokumentacji. Więcej informacji można znaleźć w sekcji 3 developer.android.com/guide/practices/…
SK9,
34
@RomainGuy można zadowolić dodać funkcję użytkową API przekonwertować z dpdo px? Dzięki.
AlikElzin-kilaka
3
co to jest dps tutaj? otrzymuję komunikat „Nie można rozwiązać problemu z DPS na zmienną”? jaki rodzaj „dps” należy zadeklarować?
Deepak
5
Zmienna „dps” to wartość wejściowa, którą chcesz przekonwertować.
Robby Pond,
233

Wiem, że to stare pytanie, ale znalazłem o wiele lepszy sposób przeprowadzenia tej konwersji.

Jawa

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

Kotlin

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65f, resources.displayMetrics)
drspaceboo
źródło
8
Dobra robota, aby dowiedzieć się, jak to zrobić. Nie jestem fanem powtarzania formuły w kilku miejscach! Dzięki.
darrenp
2
Jeśli nie, utwórz funkcję za pomocą formuły
Sayka
1
@Kenobi Dokonuje konwersji z DP do PX. 65Powyżej jest wartością DP, które mają zostać zamienione na PX
drspaceboo
7
To powinna być zaakceptowana odpowiedź, a nie obecna, skąd te liczby (0,5) pochodzą magicznie nie
wiadomo
1
@ Johny19 0,5 to nie magia. Po prostu zaokrąglij liczbę zmiennoprzecinkową do najbliższej liczby całkowitej zamiast ją obcinać. Zobacz mój komentarz do odpowiedzi Robby Pond, aby uzyskać więcej szczegółów.
MarredCheese
38

Patrząc na twoje wymagania, istnieje również alternatywne rozwiązanie. Wygląda na to, że znasz wymiary w dp w czasie kompilacji, więc możesz dodać pozycję dimen do zasobów. Następnie możesz zapytać o wpis dimen, który zostanie automatycznie przekonwertowany na piksele w tym wywołaniu:

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

A twój dimens.xml będzie miał:

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

Rozszerzając ten pomysł, możesz po prostu zapisać wartość 1dp lub 1sp jako pozycję dimen i zapytać o wartość i użyć jej jako mnożnika. Stosując to podejście, izolujesz kod od matematyki i polegasz na bibliotece, aby wykonać obliczenia.

winorośl
źródło
Zauważ, że zwracana wartość jest w rzeczywistości liczbą całkowitą, więc zostaje przekazana do liczby zmiennoprzecinkowej.
CorayThan
To zła odpowiedź, ponieważ taryfa jest dynamiczna
Johny19
37

najprostszym sposobem (a nawet działa z interfejsu API 1), który został przetestowany jest:

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

Z dokumentacji:

Pobierz wymiar dla określonego identyfikatora zasobu, aby użyć go jako rozmiaru w surowych pikselach. Jest to to samo, co getDimension (int), z tym wyjątkiem, że zwrócona wartość jest konwertowana na liczby całkowite w celu użycia jej jako rozmiaru. Konwersja rozmiaru polega na zaokrągleniu wartości podstawowej i upewnieniu się, że niezerowa wartość podstawowa ma co najmniej jeden piksel.

Tak, zaokrągla wartość, ale nie jest bardzo zła (tylko nieparzyste wartości na urządzeniach hdpi i ldpi muszą dodać niewielką wartość, gdy ldpi nie jest bardzo powszechne) Przetestowałem na urządzeniu xxhdpi, które konwertuje 4dp na 16 (piksele) i to jest prawdziwe.

David
źródło