Próbuję obliczyć zmienną liczbę pikseli do niezależnych od gęstości pikseli i odwrotnie.
Ta formuła (px to dp): dp = (int)(px / (displayMetrics.densityDpi / 160));
nie działa na małych urządzeniach, ponieważ jest podzielona przez zero.
To jest moja formuła dp do px:
px = (int)(dp * (displayMetrics.densityDpi / 160));
Czy ktoś mógłby mi udzielić wskazówek?
Odpowiedzi:
Uwaga: szeroko stosowane rozwiązanie powyżej opiera się na
displayMetrics.density
. Jednak w dokumentacji wyjaśniono, że ta wartość jest wartością zaokrągloną, używaną z „zasobnikami” ekranu. Na przykład. na moim Nexusie 10 zwraca 2, gdzie rzeczywista wartość wynosiłaby 298 dpi (rzeczywista) / 160 dpi (domyślnie) = 1,8625.W zależności od wymagań możesz potrzebować dokładnej transformacji, którą można osiągnąć w następujący sposób:
[Edytuj] To nie jest przeznaczone do mieszania z wewnętrzną jednostką dp Androida, ponieważ jest to oczywiście nadal oparte na zasobnikach ekranu. Użyj tego, jeśli chcesz, aby jednostka powinna renderować ten sam rzeczywisty rozmiar na różnych urządzeniach.
Konwertuj dp na piksel:
Konwertuj piksel na dp:
Zauważ, że istnieją właściwości xdpi i ydpi, możesz chcieć je rozróżnić, ale nie wyobrażam sobie rozsądnego wyświetlacza, w którym te wartości znacznie się różnią.
źródło
Rozwiązałem swój problem, używając następujących wzorów. Niech skorzystają na tym inni ludzie.
dp do px:
px do dp:
źródło
px do dp:
źródło
typedValue.applyDimension( TypedValue.COMPLEX_UNIT_PX, valueInDp , getResources() .getDisplayMetrics());
jest z PX na DP, również to jest najlepsza odpowiedźapplyDimension
daje tylko piksele. Zobacz android.googlesource.com/platform/frameworks/base/+/refs/heads/…, gdzie nie jest wykonywana żadna konwersjaCOMPLEX_UNIT_PX
.dp
. Jeśli spojrzeć na kod źródłowy, na razieTypedValue.COMPLEX_UNIT_DIP
,value * metrics.density
jest zwracana, gdzie rzeczywiście trzebavalue * metrics.density
. Więc czego getting` valueInDp` nie jestdp
dlavalueInPx
wpx
.value / metrics.density
”Wydajny sposób zawsze
DP na piksel:
Pixel do DP:
Mam nadzieję, że to ci pomoże.
źródło
displayMetrics.xdpi
co jest inne na każdym urządzeniu. Niestety, ta zła odpowiedź ma również najwięcej głosów pozytywnych.private fun dpToPx(dp: Int) = (dp * Resources.getSystem().displayMetrics.density).toInt()
Po prostu zadzwoń,
getResources().getDimensionPixelSize(R.dimen.your_dimension)
aby przekonwertować zdp
jednostek na pikseleźródło
Użyj tej funkcji
źródło
źródło
(displayMetrics.densityDpi / 160)
- ta część może otrzymać 0 na małych urządzeniach, tam na przykład oblicza120/160
, obie wartości są int, co daje 0. Co kończy się jako(int) (px/0)
.W większości przypadków funkcje konwersji są wywoływane często. Możemy to zoptymalizować dodając zapamiętywanie. Dlatego nie wykonuje obliczeń za każdym razem, gdy wywoływana jest funkcja.
Zadeklarujmy HashMap, który będzie przechowywać obliczone wartości.
Funkcja obliczająca wartości pikseli:
Funkcja zapamiętywania, która zwraca wartość z HashMap i przechowuje zapis poprzednich wartości.
Memoizacja może być implementowana na różne sposoby w Javie. Dla Java 7 :
Java 8 obsługuje funkcję Lambda :
Dzięki.
źródło
spróbuj tego http://labs.skinkers.com/content/android_dp_px_calculator/
źródło
Poniższe funkcje działały dobrze dla mnie na różnych urządzeniach.
Pochodzi z https://gist.github.com/laaptu/7867851
źródło
Możesz użyć
[DisplayMatrics][1]
i określić gęstość ekranu. Coś takiego:O ile dobrze pamiętam, do odsadzeń i zaokrąglania na szerokościach lepiej jest używać podłóg.
źródło
Jeśli szukasz kalkulatora online do przeliczania DP, SP, cali, milimetrów, punktów lub pikseli na i między sobą przy różnych gęstościach ekranu, jest to najbardziej kompletne narzędzie, jakie znam .
źródło
// do uzyskania wartości Decimal / Float
________________________________________________________________________________
źródło
Użyj tych rozszerzeń Kotlin:
źródło
Zapraszam do skorzystania z tej metody, którą napisałem:
źródło
Przyjęta powyżej odpowiedź nie jest w pełni poprawna. Według informacji uzyskanych podczas inspekcji kodu źródłowego Androida:
Resources.getDimension()
igetDimensionPixelOffset()
/getDimensionPixelSize()
różnią się tylko tym, że pierwszy zwraca,float
podczas gdy dwa ostatnie zwracają tę samą wartośćint
odpowiednio zaokrągloną . Dla wszystkich zwracana jest wartość w surowych pikselach.Wszystkie trzy funkcje są implementowane przez wywołanie
Resources.getValue()
i konwersję uzyskaną w ten sposóbTypedValue
przez wywołanie , odpowiednioTypedValue.complexToDimension()
,TypedValue.complexToDimensionPixelOffset()
iTypedValue.complexToDimensionPixelSize()
.Dlatego jeśli chcesz uzyskać „surową” wartość razem z jednostką określoną w źródle XML, wywołaj
Resources.getValue()
i użyj metodTypedValue
klasy.źródło
z pomocą innych odpowiedzi napisałem tę funkcję.
źródło
Oto inny sposób na zrobienie tego za pomocą rozszerzeń kotlin:
a następnie może być używany w ten sposób z dowolnego miejsca
źródło
źródło
odmiana odpowiedzi ct_robs powyżej, jeśli używasz liczb całkowitych, które nie tylko pozwalają uniknąć dzielenia przez 0, ale także dają użyteczny wynik na małych urządzeniach:
w obliczeniach całkowitych obejmujących dzielenie w celu uzyskania największej dokładności należy najpierw pomnożyć przed podzieleniem, aby zredukować efekty obcięcia.
zamiast
jeśli chcesz zaokrąglony wynik, zrób to
źródło