我创建了我的应用程序,其高度和宽度以像素为单位,用于分辨率为480x800的Pantech设备。
我需要转换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()
);
因此,您可以使用以下配方设计器从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);
}
对于使用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
android SDK中有一个默认的util:http://developer.android.com/reference/android/util/TypedValue.html
float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
这应该给你转换dp到像素:
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
这应该给你转换像素到dp:
public static int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
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);
}
使用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
是global shared Resources的一部分,我们可以使用Resources.getSystem()
fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()
fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()
可能最好的方法是,如果你有维度在值/维度内是直接从getDimension()方法获取维度,它将返回已经转换为像素值的维度。
context.getResources().getDimension(R.dimen.my_dimension)
为了更好地解释这一点,
getDimension(int resourceId)
将返回已转换为像素AS A FLOAT的尺寸。
getDimensionPixelSize(int resourceId)
将返回相同但截断为int,因此AS AN INTEGER。
public static int dp2px(Resources resource, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,resource.getDisplayMetrics());
}
To convert pixel to dp.
public static float px2dp(Resources resource, float px) {
return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}
其中资源是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;
}
}
依赖于Context,返回浮点值,静态方法
如果您正在开发性能关键型应用程序,请考虑以下优化类:
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;
}
}
/**
* 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);
}
使用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}")
将像素转换为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());
希望有助于。
float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);
这是它对我有用的方式:
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
,除非你转换它们。
所以在Android设备上,正常大小的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);
如果你想要Integer值,那么使用Math.round()会将float舍入到最接近的整数。
public static int pxFromDp(final float dp) {
return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
}
科特林
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
}
java的
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;
}
最好放在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;
}
对于Xamarin.Android
float DpToPixel(float dp)
{
var resources = Context.Resources;
var metrics = resources.DisplayMetrics;
return dp * ((float)metrics.DensityDpi / (int)DisplayMetricsDensity.Default);
}
在制作自定义渲染器时,必须使其成为非静态渲染器
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)使用此online converter来播放dpi值。
编辑:似乎dpi
斗和density
之间没有1:1的关系。看起来Nexus 5X
是xxhdpi
有density
值2.625
(而不是3
)。在Device Metrics看看你自己。
如果你可以使用尺寸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);
根据Android开发指南:
px = dp * (dpi / 160)
但是,当您收到以像素为单位的设计时,通常您会希望以相反的方式执行此操作。所以:
dp = px / (dpi / 160)
如果您使用的是240dpi设备,则此比率为1.5(如前所述),因此这意味着应用程序中的60px图标等于40dp。
您可以使用此..没有上下文
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来做到这一点。
没有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);
}
对于DP to Pixel
在dimens.xml
中创建一个值
<dimen name="textSize">20dp</dimen>
在pixel
获取该值为:
int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);