我已经按像素为 Pantech 设备创建了应用程序,其分辨率为 480x800
。
我需要将高度和宽度转换为 G1 设备。
我认为将其转换为 dp 可以解决问题,并为两个设备提供相同的解决方案。
有没有简单的方法将像素转换为 dp?
有什么建议吗?
我已经按像素为 Pantech 设备创建了应用程序,其分辨率为 480x800
。
我需要将高度和宽度转换为 G1 设备。
我认为将其转换为 dp 可以解决问题,并为两个设备提供相同的解决方案。
有没有简单的方法将像素转换为 dp?
有什么建议吗?
Java代码:
// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
Kotlin 代码:
val dip = 14f
val r: Resources = resources
val px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.displayMetrics
)
fun Context.toPx(dp: Int): Float = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp.toFloat(),
resources.displayMetrics)
applyDimension
的最后一个参数?我可以只用 getResource().getDisplayMetrics()
吗,还是还有其他方法? - AndyContext
对象,则使用 Resources.getSystem().getDisplayMetrics()
。 - Farshad Tahmasbi/**
* 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()
文档(重点标注为我的部分):返回一个全局共享的Resources
对象,仅提供对系统资源(不包括应用程序资源)的访问,并且未针对当前屏幕进行配置(无法使用尺寸单位,不会随方向更改等)。 - Vicky ChijwaniDisplayMetrics.DENSITY_DEFAULT
代替160f
。参考链接:http://developer.android.com/reference/android/util/DisplayMetrics.html#DENSITY_DEFAULT - milcaepsilonpublic 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
的值如下:
ldpi
(120
dpi)为.75
mdpi
(160
dpi;基准)为1.0
hdpi
(240
dpi)为1.5
xhdpi
(320
dpi)为2.0
xxhdpi
(480
dpi)为3.0
xxxhdpi
(640
dpi)为4.0
使用此在线转换器来尝试不同的dpi值。
编辑:
似乎dpi
桶和density
之间没有1:1的关系。例如Nexus 5X
是xxhdpi
,其density
值为2.625
(而非3
)。您可以在设备指标中自行查看。
您可以在没有上下文的情况下使用此内容(without 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提到的一样...使用这种方法可能会导致问题,如果系统改变了密度,请注意!
个人而言,我正在使用Context来做到这一点。这只是我想与您分享的另一种方法。
如果您可以使用dimensions 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。没有上下文
,优雅的静态方法:
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 描述为“返回一个全局共享的 Resources 对象,仅提供对系统资源(而非应用资源)的访问,并且没有针对当前屏幕进行配置(不能使用尺寸单位,不会根据方向改变等)。” 这基本上意味着,即使它能够工作,你也不应该这样做。 - Austyn Mahoney使用Kotlin扩展可以使其更好
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的一部分,因此我们可以使用Resources.getSystem()
val Float.toPx get() = this * Resources.getSystem().displayMetrics.density
val Float.toDp get() = this / Resources.getSystem().displayMetrics.density
val Int.toPx get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp get() = (this / Resources.getSystem().displayMetrics.density).toInt()
提示:根据@EpicPandaForce的评论:
您不应该使用Resources.getSystem(),因为它无法处理可折叠设备和Chrome OS设备。
Resources.getSystem()
进行此操作,因为它无法处理可折叠设备和 Chrome OS 设备。 - EpicPandaForce对于使用 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
roundToInt()
比toInt()
稍微好一些。 - Adam Johns
px
、dp
、sp
转换公式:在 Android 中,px
表示像素,是屏幕上的一个点;dp
表示密度无关像素,它会根据屏幕密度进行缩放;sp
表示可缩放像素,通常用于文本字号大小。以下是相互转化的公式:px
todp
:dp = px / (dpi / 160)
dp
topx
:px = dp * (dpi / 160)
sp
topx
:px = sp * (dpi / 160)
dpi
是指每英寸包含的像素数。 - Suragch