2010-02-10 2 views
51

Java 코드에서 DIP의 치수를 지정하는 올바른 방법은 무엇입니까?

다음 코드에서와 같이 DIP를 사용하여 XML 레이아웃에서 인터페이스 요소의 크기를 설정할 수 있다는 것을 알았습니다.

android:layout_width="10dip" 

그러나 모든 Java 인터페이스는 정수를 인수로 취하므로 DIP에서 차원을 지정할 방법이 없습니다. 이것을 계산하는 올바른 방법은 무엇입니까?

DisplayMetrics 클래스의 속성 밀도를 사용해야하지만 올바른 방법이라고 생각했습니다.

이 수식에 항상 의지 할 수 있습니까?

픽셀 * DisplayMetrics.density = dip

안드로이드 어딘가에 변환을위한 유틸리티 함수가 있습니까?

답변

43

그곳에 올바른 공식이 있습니다. DisplayMetrics.density는 정적 멤버는 아니지만, 그래서 same document you alluded to에 따라, 올바른 사용법은 다음과 같습니다

// Maybe store this in a static field? 
final float SCALE = getContext().getResources().getDisplayMetrics().density; 

// Convert dips to pixels 
float valueDips = 16.0f; 
int valuePixels = (int)(valueDips * SCALE + 0.5f); // 0.5f for rounding 
+1

감사합니다. 로마인, 어떻게 든이 부분을 간과했습니다. 주제와 관련된 두 가지 질문이 있습니다 : - 밀도가 항상 양쪽 치수에서 동일합니까? 그것은 (이것은 단지 하나의 값이기 때문에) 그렇지만 아마도 이것을 계산하는 다른 공식이있을 것입니다. - 저에게 변환을 수행 할 API가 없습니까? 내 코드에 다음 코드를 써야하나요?XML 레이아웃 코드에서 "dip"을 단위로 지정할 수 있습니다. 왜 Java API에서는 불가능합니까? –

+1

두 밀도에서 밀도가 동일하다고 가정 할 수 있다고 생각합니다. DisplayMetrics.density는 실제 화면 밀도가 아닌 논리적 밀도 **입니다 (논리적 밀도와 약간 다를 수 있음). 변환 API에 관해서는 함수 호출에 사용하기 위해 dip을 픽셀로 변환하는 'Util.dip'과 같은 도우미 메서드를 작성하는 것이 쉽습니다. Java에서 유닛을 그런 방식으로 처리하는 것이 더 깔끔합니다. –

91

는이 작업을 수행 TypedValue.applyDimensions(int, float, DisplayMetrics)라는 내장 기존의 유틸리티 메소드가있다.

는 여기를 사용하는 방법은 다음과 같습니다

당신이 내가 위의 링크 된 페이지에있는 COMPLEX_UNIT_SP, COMPLEX_UNIT_PT을 모두 포함하여 함께 사용할 수있는 다른 유형의 목록이있다
// returns the number of pixels for 123.4dip 
int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 
        (float) 123.4, getResources().getDisplayMetrics()); 

. (int) 타입 변환을 제외하면 부동 소수점 숫자가 생깁니다.

동일한 문제가 발생하여 코드를 샅샅이 뒤져서 발견했습니다.

+12

이것은 픽셀을 DIP 대신 DIP로 변환하여 OP가 원했던 픽셀로 변환합니다. 확실히 그것은 내가 원했던 것입니다. 당신이 좋아하는 것은 :'(int) (desiredDIP * context.getResources(). getDisplayMetrics(). density)' – mxcl

9

디스플레이 메트릭 밀도 필드를 사용하면 축소/축소 변환 계수를 얻을 수 있습니다. 캐스트를 필요로 0.5

// Converting dips to pixels 
float dips = 20.0f; 
float scale = getContext().getResources().getDisplayMetrics().density; 
int pixels = Math.round(dips * scale); 

// Converting pixels to dips 
int pixels = 15; 
float scale = getContext().getResources().getDisplayMetrics().density; 
float dips = pixels/scale; 
+0

Math.round는 캐스트를 수행합니다. '(int) Math.floor (a + 0.5f)'는 Math.round가 처리하는 것입니다. –

5

를 추가하지 않고 int로 부동 소수점으로 변환 할 수 Math.round 방법을 사용 나는 가장 좋은 방법은 코드의 모든 차원을 정의 대신 values/dimens.xml 파일을 사용하지 않는 것입니다 생각합니다.

<dimen name="my_layout_height">120dp</dimen> 

을 다음처럼 활동이 참조 : 당신은 항상 같은 원하는 단위에서 차원을 정의 할 수 있습니다이 필요한 변환을 수행 한 후 픽셀을 반환

getResources().getDimensions(R.dimen.my_layout_height); 

. 그리고 물론 다른 XML에서도 다음과 같이 참조 할 수 있습니다 :

android:layout_width="@dimen/my_layout_height"