해상도가 팬택 장치 인 픽셀의 높이와 너비를 사용하여 응용 프로그램을 만들었습니다 480x800
.
G1 장치의 높이와 너비를 변환해야합니다.
dp로 변환하면 문제를 해결하고 두 장치에 동일한 솔루션을 제공 할 것이라고 생각했습니다.
픽셀을 DP로 변환하는 쉬운 방법이 있습니까?
어떤 제안?
해상도가 팬택 장치 인 픽셀의 높이와 너비를 사용하여 응용 프로그램을 만들었습니다 480x800
.
G1 장치의 높이와 너비를 변환해야합니다.
dp로 변환하면 문제를 해결하고 두 장치에 동일한 솔루션을 제공 할 것이라고 생각했습니다.
픽셀을 DP로 변환하는 쉬운 방법이 있습니까?
어떤 제안?
답변:
// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
applyDimension
어떻게 얻을 수 있습니까? 방금 할 수 있습니까 getResource().getDisplayMetrics()
, 아니면 다른 것이 있습니까?
Context
객체 사용Resources.getSystem().getDisplayMetrics()
/**
* This method converts dp unit to equivalent pixels, depending on device density.
*
* @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
* @param context Context to get resources and device specific display metrics
* @return A float value to represent px equivalent to dp depending on device density
*/
public static float convertDpToPixel(float dp, Context context){
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
/**
* This method converts device specific pixels to density independent pixels.
*
* @param px A value in px (pixels) unit. Which we need to convert into db
* @param context Context to get resources and device specific display metrics
* @return A float value to represent dp equivalent to px value
*/
public static float convertPixelsToDp(float px, Context context){
return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
Resource.getSystem()
(강조 광산) : "시스템 자원 (응용 프로그램 자원 없음)에만 액세스 할 수 있고 현재 화면에 대해 구성되지 않은 전역 공유 자원 오브젝트를 리턴하십시오 ( 차원 단위를 사용할 수 없으며 변경되지 않음) 방향 등을 기준으로합니다. ")
바람직하게는 Util.java 클래스에 넣습니다.
public static float dpFromPx(final Context context, final float px) {
return px / context.getResources().getDisplayMetrics().density;
}
public static float pxFromDp(final Context context, final float dp) {
return dp * context.getResources().getDisplayMetrics().density;
}
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;
density
같다
.75
켜기 ldpi
( 120
dpi)1.0
켜기 mdpi
( 160
dpi; 기준선)1.5
켜기 hdpi
( 240
dpi)2.0
켜기 xhdpi
( 320
dpi)3.0
켜기 xxhdpi
( 480
dpi)4.0
켜기 xxxhdpi
( 640
dpi)이 온라인 변환기 를 사용 하여 dpi 값으로 재생 하십시오 .
편집 : dpi
bucket과와 1 : 1 관계가없는 것 같습니다 density
. Nexus 5X
존재 xxhdpi
는의 density
값이 2.625
아닌 것 같습니다 3
. 장치 메트릭 에서 직접 확인하십시오 .
Context없이 이것을 사용할 수 있습니다.
public static int pxToDp(int px) {
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
public static int dpToPx(int dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
@Stan이 언급했듯이 ..이 방법을 사용하면 시스템의 밀도가 변경되면 문제가 발생할 수 있습니다. 그러니 알아 두세요!
개인적으로 나는 그것을하기 위해 컨텍스트를 사용하고 있습니다. 내가 당신과 공유하고 싶었던 또 다른 접근법 일뿐입니다.
XML 크기를 사용할 수 있다면 매우 간단합니다!
당신의 res/values/dimens.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="thumbnail_height">120dp</dimen>
...
...
</resources>
그런 다음 Java에서 :
getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
안드로이드 개발 가이드에 따르면 :
px = dp * (dpi / 160)
그러나 종종 픽셀로 표시된 디자인을받을 때 다른 방법으로이 작업을 수행하려고합니다. 그래서:
dp = px / (dpi / 160)
240dpi 장치를 사용하는 경우이 비율은 1.5 (이전에 언급 한 것처럼)이므로 응용 프로그램에서 60px 아이콘이 40dp와 같습니다.
Context
우아한 정적 메소드가 없으면 :
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
public static int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
Resources.getSystem()
javadoc은 "응용 프로그램 자원이없는 시스템 자원에만 액세스 할 수 있고 현재 화면에 대해 구성되지 않은 전역 공유 자원 오브젝트를 리턴합니다 (차원 단위를 사용할 수없고 방향에 따라 변경되지 않음"). 이것은 어떻게 든 작동 하더라도이 작업을 수행해서는 안된다고 말합니다.
따라서 다음 공식을 사용하여 dp에 지정된 차원에서 올바른 픽셀 수를 계산할 수 있습니다
public int convertToPx(int dp) {
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (dp * scale + 0.5f);
}
convertToDp
.
Kotlin을 사용하는 사람 :
val Int.toPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
용법:
64.toPx
32.toDp
안드로이드 SDK에는 기본 유틸리티가 있습니다 : http://developer.android.com/reference/android/util/TypedValue.html
float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
resultPix
int 유형이어야합니다. int resultPix = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
kotlin-extension을 사용하면 더 좋습니다.
fun Int.toPx(context: Context): Int = (this * context.resources.displayMetrics.density).toInt()
fun Int.toDp(context: Context): Int = (this / context.resources.displayMetrics.density).toInt()
최신 정보:
때문에 중 displayMetrics
의 일부 글로벌 공유 자원 , 우리가 사용할 수 있습니다Resources.getSystem()
fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()
fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()
fun convertDpToPixel(dp: Float, context: Context): Float {
return dp * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
fun convertPixelsToDp(px: Float, context: Context): Float {
return px / (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
public static float convertDpToPixel(float dp, Context context) {
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
public static float convertPixelsToDp(float px, Context context) {
return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
아마도 치수 / 값에 치수가있는 경우 가장 좋은 방법은 getDimension () 메서드에서 직접 치수를 얻는 것입니다. 이미 픽셀 값으로 변환 된 치수를 반환합니다.
context.getResources().getDimension(R.dimen.my_dimension)
이것을 더 잘 설명하기 위해
getDimension(int resourceId)
FLOAT로 이미 픽셀로 변환 된 치수를 반환합니다.
getDimensionPixelSize(int resourceId)
동일하지만 int로 잘린 상태로 반환되므로 INTEGER 그대로.
안드로이드 참조 보기
public static int dp2px(Resources resource, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,resource.getDisplayMetrics());
}
픽셀을 dp로 변환합니다.
public static float px2dp(Resources resource, float px) {
return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}
여기서 resource는 context.getResources ()입니다.
이처럼 :
public class ScreenUtils {
public static float dpToPx(Context context, float dp) {
if (context == null) {
return -1;
}
return dp * context.getResources().getDisplayMetrics().density;
}
public static float pxToDp(Context context, float px) {
if (context == null) {
return -1;
}
return px / context.getResources().getDisplayMetrics().density;
}
}
컨텍스트에 따라 다름, float 값 반환, 정적 메소드
kotlin의 확장 기능을 사용한보다 우아한 접근 방식
/**
* Converts dp to pixel
*/
val Int.dpToPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt()
/**
* Converts pixel to dp
*/
val Int.pxToDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt()
용법:
println("16 dp in pixel: ${16.dpToPx}")
println("16 px in dp: ${16.pxToDp}")
function name
이 경우에는 "역시 변환"기능을 거꾸로 읽습니다 . 각 함수의 의도를 명확히하기 위해 dpToPx 및 pxToDp를 각각 읽도록 함수 이름을 업데이트 할 수 있습니다.
성능이 중요한 응용 프로그램을 개발하는 경우 다음 최적화 클래스를 고려하십시오.
public final class DimensionUtils {
private static boolean isInitialised = false;
private static float pixelsPerOneDp;
// Suppress default constructor for noninstantiability.
private DimensionUtils() {
throw new AssertionError();
}
private static void initialise(View view) {
pixelsPerOneDp = view.getResources().getDisplayMetrics().densityDpi / 160f;
isInitialised = true;
}
public static float pxToDp(View view, float px) {
if (!isInitialised) {
initialise(view);
}
return px / pixelsPerOneDp;
}
public static float dpToPx(View view, float dp) {
if (!isInitialised) {
initialise(view);
}
return dp * pixelsPerOneDp;
}
}
픽셀을 dp로 변환하려면 TypedValue를 사용하십시오 .
문서에서 언급 한 바와 같이 : 동적으로 형식화 된 데이터 값을위한 컨테이너.
applyDimension 메소드를 사용하십시오 .
public static float applyDimension (int unit, float value, DisplayMetrics metrics)
차원을 보유한 압축 해제 된 복합 데이터 값을 다음과 같이 최종 부동 소수점 값으로 변환합니다.
Resources resource = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics());
희망이 도움이됩니다.
이것이 나를 위해 작동하는 방법입니다.
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int h = displaymetrics.heightPixels;
float d = displaymetrics.density;
int heightInPixels=(int) (h/d);
너비에 대해서도 동일한 작업을 수행 할 수 있습니다.
픽셀처럼 dp를 사용해야합니다. 그것이 전부입니다. 독립 픽셀을 표시합니다. 중간 밀도 화면에서와 같은 숫자를 사용하면 고밀도 화면에서 크기가 마술처럼 정확합니다.
그러나 레이아웃 디자인의 fill_parent 옵션이 필요한 것 같습니다. 뷰 또는 컨트롤을 부모 컨테이너의 나머지 모든 크기로 확장하려면 fill_parent를 사용하십시오.
PX
와 DP
다르지만 비슷합니다.
DP
화면의 실제 크기 만 고려할 때의 해상도입니다. 사용 DP
하면 pixel
밀도 가 다른 다른 비슷한 크기의 화면으로 레이아웃이 조정됩니다 .
때로는 실제로 원 pixels
하지만 코드에서 치수를 처리 할 때 pixels
변환하지 않는 한 항상 real을 처리 합니다.
따라서 안드로이드 장치, 보통 크기의 hdpi
화면 800x480 is 533x320
에서 DP
(믿습니다). 변환하려면 DP
로 pixels /1.5
다시 변환 할 *1.5
. 이것은 한 화면 크기에만 dpi
적용되며 디자인에 따라 달라집니다. 우리 예술가들은 나에게 줄 것이고 위의 방정식으로 pixels
변환합니다 .DP
1.5
이것은 나를 위해 일했습니다 (C #).
int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);
코 틀린
fun spToPx(ctx: Context, sp: Float): Float {
return sp * ctx.resources.displayMetrics.scaledDensity
}
fun pxToDp(context: Context, px: Float): Float {
return px / context.resources.displayMetrics.density
}
fun dpToPx(context: Context, dp: Float): Float {
return dp * context.resources.displayMetrics.density
}
자바
public static float spToPx(Context ctx,float sp){
return sp * ctx.getResources().getDisplayMetrics().scaledDensity;
}
public static float pxToDp(final Context context, final float px) {
return px / context.getResources().getDisplayMetrics().density;
}
public static float dpToPx(final Context context, final float dp) {
return dp * context.getResources().getDisplayMetrics().density;
}
가장 좋은 대답은 안드로이드 프레임 워크 자체에서 나옵니다.이 평등을 사용하십시오 ...
public static int dpToPixels(final DisplayMetrics display_metrics, final float dps) {
final float scale = display_metrics.density;
return (int) (dps * scale + 0.5f);
}
(dp를 px로 변환)