我创建的应用程序的分辨率是的Pantech设备的高度和宽度(以像素为单位)480x800
。
我需要为G1设备转换高度和宽度。
我认为将其转换为dp可以解决问题,并为两种设备提供相同的解决方案。
有没有简单的方法可以将像素转换为dp?
有什么建议么?
我创建的应用程序的分辨率是的Pantech设备的高度和宽度(以像素为单位)480x800
。
我需要为G1设备转换高度和宽度。
我认为将其转换为dp可以解决问题,并为两种设备提供相同的解决方案。
有没有简单的方法可以将像素转换为dp?
有什么建议么?
Answers:
// 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
桶和之间没有1:1关系density
。看起来该Nexus 5X
存在物xxhdpi
的density
值为2.625
(而不是3
)。自己查看“ 设备指标”。
您可以在没有上下文的情况下使用此..
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来做到这一点的。这是我想与您分享的另一种方法
如果可以使用维度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);
没有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
android SDK中有一个默认util: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扩展使它更好
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)
将返回已转换为像素的尺寸为A FLOAT。
getDimensionPixelSize(int resourceId)
将返回相同但被截断为int的值,因此为AS INTEGER。
请参阅Android参考
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());
}
资源是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;
}
}
取决于上下文,返回浮点值,静态方法
来自:https : //github.com/Trinea/android-common/blob/master/src/cn/trinea/android/common/util/ScreenUtils.java#L15
使用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;
}
}
要将Pixels转换为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。
如果需要Integer值,则使用Math.round()会将float舍入到最接近的整数。
public static int pxFromDp(final float dp) {
return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
}
这对我有用(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;
}
最好的答案来自Android框架本身:只需使用这种相等性即可...
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)