我创建了一些自定义元素,并希望以编程方式将它们放置在右上角(距离上边缘n个像素,距离右边缘m个像素)。因此,我需要获得屏幕宽度和屏幕高度,然后设置位置:

int px = screenWidth - m;
int py = screenHeight - n;

如何在主活动中获取screenWidth和screenHeight?


当前回答

我尝试了所有可能的“解决方案”,但都失败了,我注意到Elliott Hughes的“Dalvik Explorer”应用程序在任何Android设备/操作系统版本上都始终显示正确的维度。我最后看了他的开源项目,可以在这里找到:https://code.google.com/p/enh/

以下是所有相关代码:

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

EDIT:略有改进的版本(避免在不受支持的OS版本上触发异常):

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

其他回答

为了访问Android设备的状态栏高度,我们更喜欢一种编程方式:

示例代码

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    result = getResources().getDimensionPixelSize(resId);
}

变量结果给出像素的高度。

用于快速访问

有关标题栏、导航栏和内容视图高度的更多信息,请查看Android设备屏幕大小。

简单的功能与较低版本兼容。

/**
 * @return screen size int[width, height]
 *
 * */
public int[] getScreenSize(){
    Point size = new Point();
    WindowManager w = getWindowManager();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
        w.getDefaultDisplay().getSize(size);
        return new int[]{size.x, size.y};
    }else{
        Display d = w.getDefaultDisplay();
        //noinspection deprecation
        return new int[]{d.getWidth(), d.getHeight()};
    }
}

要使用:

int width = getScreenSize()[0];
int height = getScreenSize()[1];

•Kotlin版本通过扩展属性

在android中有多种实现屏幕尺寸的方法,但我认为最好的解决方案可以独立于Context实例,因此您可以在代码中的任何地方使用它。在这里,我通过kotlin扩展属性提供了一个解决方案,它可以很容易地知道以像素为单位的屏幕大小以及dp:


尺寸Utils.kt

import android.content.res.Resources
import android.graphics.Rect
import android.graphics.RectF
import android.util.DisplayMetrics
import kotlin.math.roundToInt

/**
 * @author aminography
 */

private val displayMetrics: DisplayMetrics by lazy { Resources.getSystem().displayMetrics }

val screenRectPx: Rect
    get() = displayMetrics.run { Rect(0, 0, widthPixels, heightPixels) }

val screenRectDp: RectF
    get() = displayMetrics.run { RectF(0f, 0f, widthPixels.px2dp, heightPixels.px2dp) }

val Number.px2dp: Float
    get() = this.toFloat() / displayMetrics.density

val Number.dp2px: Int
    get() = (this.toFloat() * displayMetrics.density).roundToInt()


用法:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val widthPx = screenRectPx.width()
        val heightPx = screenRectPx.height()
        println("[PX] screen width: $widthPx , height: $heightPx")

        val widthDp = screenRectDp.width()
        val heightDp = screenRectDp.height()
        println("[DP] screen width: $widthDp , height: $heightDp")
    }
}

结果:

当设备处于纵向时:

[PX] screen width: 1440 , height: 2392
[DP] screen width: 360.0 , height: 598.0

当设备处于横向时:

[PX] screen width: 2392 , height: 1440
[DP] screen width: 598.0 , height: 360.0


如果您不是kotlin的粉丝,请使用java版本:

import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.DisplayMetrics;

/**
 * @author aminography
 */
public class DimensionUtils {

    private static DisplayMetrics displayMetrics;

    private static DisplayMetrics getDisplayMetrics() {
        if (displayMetrics == null) {
            displayMetrics = Resources.getSystem().getDisplayMetrics();
        }
        return displayMetrics;
    }

    public static Rect screenRectPx() {
        return new Rect(0, 0, getDisplayMetrics().widthPixels, getDisplayMetrics().heightPixels);
    }

    public static RectF screenRectDp() {
        return new RectF(0f, 0f, px2dp(getDisplayMetrics().widthPixels), px2dp(getDisplayMetrics().heightPixels));
    }

    public static float px2dp(int value) {
        return value / getDisplayMetrics().density;
    }

    public static int dp2px(float value) {
        return (int) (value * getDisplayMetrics().density);
    }
}

如果Display类不工作,则上面的答案将不起作用,那么您可以通过下面的方法获得宽度和高度。

private static final int WIDTH_INDEX = 0;
private static final int HEIGHT_INDEX = 1;

    public static int[] getScreenSize(Context context) {
        int[] widthHeight = new int[2];
        widthHeight[WIDTH_INDEX] = 0;
        widthHeight[HEIGHT_INDEX] = 0;

        try {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();

            Point size = new Point();
            display.getSize(size);
            widthHeight[WIDTH_INDEX] = size.x;
            widthHeight[HEIGHT_INDEX] = size.y;

            if (!isScreenSizeRetrieved(widthHeight))
            {
                DisplayMetrics metrics = new DisplayMetrics();
                display.getMetrics(metrics);
                widthHeight[0] = metrics.widthPixels;
                widthHeight[1] = metrics.heightPixels;
            }

            // Last defense. Use deprecated API that was introduced in lower than API 13
            if (!isScreenSizeRetrieved(widthHeight)) {
                widthHeight[0] = display.getWidth(); // deprecated
                widthHeight[1] = display.getHeight(); // deprecated
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return widthHeight;
    }

    private static boolean isScreenSizeRetrieved(int[] widthHeight) {
        return widthHeight[WIDTH_INDEX] != 0 && widthHeight[HEIGHT_INDEX] != 0;
    }
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;