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

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

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


当前回答

(2012年的答案,可能已经过时了)如果你想支持前蜂窝,你需要在API 13之前引入向后兼容性。类似于:

int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    Point size = new Point();
    w.getDefaultDisplay().getSize(size);
    measuredWidth = size.x;
    measuredHeight = size.y;
} else {
    Display d = w.getDefaultDisplay();
    measuredWidth = d.getWidth();
    measuredHeight = d.getHeight();
}

当然,被弃用的方法最终会从最新的SDK中删除,但尽管我们仍然依赖大多数拥有Android 2.1、2.2和2.3的用户,但这就是我们剩下的。

其他回答

我有两个函数,一个用于发送上下文,另一个用于获取像素的高度和宽度:

public static int getWidth(Context mContext){
    int width=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        width = size.x;
    }
    else{
        width = display.getWidth();  // Deprecated
    }
    return width;
}

and

public static int getHeight(Context mContext){
    int height=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        height = size.y;
    }
    else{
        height = display.getHeight();  // Deprecated
    }
    return height;
}

首先获取视图(例如,通过findViewById()),然后可以对视图本身使用getWidth()。

这里是Kotlin实现中对上面一些答案的简单改编。它需要清单中如上所述的windowsSoftInput=“adjustResize”:

class KeyboardWatcher(private val layoutRooView: View) {

    companion object {
        private const val MIN_KEYBOARD_HEIGHT = 200f
    }

    private val displayMetrics: DisplayMetrics = layoutRooView.resources.displayMetrics
    private var stateVisible = false

    var observer: ((Boolean) -> Unit)? = null

    init {
        layoutRooView.viewTreeObserver.addOnGlobalLayoutListener {
            val heightDiff = layoutRooView.rootView.height - layoutRooView.height
            if (!stateVisible && heightDiff > dpToPx(MIN_KEYBOARD_HEIGHT)) {
                stateVisible = true
                observer?.invoke(stateVisible)
            } else if(stateVisible) {
                stateVisible = false
                observer?.invoke(stateVisible)
            }
        }
    }

    private fun dpToPx(valueInDp: Float): Float {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, displayMetrics)
    }
}

并使用:

val activityRootView = findViewById<ViewGroup>(R.id.activityRoot)
KeyboardWatcher(activityRootView).observer = { visible ->
    if (visible) do something here ...
}

首先加载XML文件,然后编写以下代码:

setContentView(R.layout.main);      
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());

根据屏幕分辨率显示宽度和高度。

以上代码已在API级别30中弃用。现在您可以使用以下代码

 val width = windowManager.currentWindowMetrics.bounds.width()
 val height = windowManager.currentWindowMetrics.bounds.height()

此方法报告包括所有系统栏区域的窗口大小,而Display#getSize(Point)报告不包括导航栏和显示剪切区域的区域。Display#getSize(Point)报告的值可通过以下方式获得:

 val metrics = windowManager.currentWindowMetrics
 // Gets all excluding insets
 val windowInsets = metrics.windowInsets
 var insets: Insets = windowInsets.getInsets(WindowInsets.Type.navigationBars())
 val cutout = windowInsets.displayCutout
 if (cutout != null) {
    val cutoutSafeInsets = Insets.of(cutout.safeInsetLeft, cutout.safeInsetTop, cutout.safeInsetRight, cutout.safeInsetBottom)
    insets = Insets.max(insets, cutoutSafeInsets)
 }

 val insetsWidth = insets.right + insets.left
 val insetsHeight = insets.top + insets.bottom

 // Legacy size that Display#getSize reports
 val legacySize =  Size(metrics.bounds.width() - insetsWidth, metrics.bounds.height() - insetsHeight)

来源:WindowManager#getCurrentWindowMetrics()