我创建了一些自定义元素,并希望以编程方式将它们放置在右上角(距离上边缘n个像素,距离右边缘m个像素)。因此,我需要获得屏幕宽度和屏幕高度,然后设置位置:
int px = screenWidth - m;
int py = screenHeight - n;
如何在主活动中获取screenWidth和screenHeight?
我创建了一些自定义元素,并希望以编程方式将它们放置在右上角(距离上边缘n个像素,距离右边缘m个像素)。因此,我需要获得屏幕宽度和屏幕高度,然后设置位置:
int px = screenWidth - m;
int py = screenHeight - n;
如何在主活动中获取screenWidth和screenHeight?
当前回答
以上代码已在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()
其他回答
需要说明的是,如果您不在“活动”中,而是在“视图”中(或在范围中具有视图类型的变量),则不需要使用WINDOW_SERVICE。那么你至少可以使用两种方法。
第一:
DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();
第二:
DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);
我们在这里调用的所有这些方法都没有被弃用。
在“活动”中使用以下代码。
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;
这里是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 ...
}
我有一个启动屏幕活动,LinearLayout作为根视图,其宽度和高度为match_parent。这是该活动的onCreate()方法中的代码。我在应用程序的所有其他活动中使用这些度量。
int displayWidth = getRawDisplayWidthPreHoneycomb();
int rawDisplayHeight = getRawDisplayHeightPreHoneycomb();
int usableDisplayHeight = rawDisplayHeight - getStatusBarHeight();
pf.setScreenParameters(displayWidth, usableDisplayHeight);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
LinearLayout myView = (LinearLayout) findViewById(R.id.splash_view);
myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (left == 0 && top == 0 && right == 0 && bottom == 0) {
return;
}
int displayWidth = Math.min(right, bottom);
int usableDisplayHeight = Math.max(right, bottom);
pf.setScreenParameters(displayWidth, usableDisplayHeight);
}
});
}
下面是上面调用的方法的实现:
private int getRawDisplayWidthPreHoneycomb() {
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
int widthPixels = displayMetrics.widthPixels;
int heightPixels = displayMetrics.heightPixels;
return Math.min(widthPixels, heightPixels);
}
private int getRawDisplayHeightPreHoneycomb() {
WindowManager w = getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;
return Math.max(widthPixels, heightPixels);
}
public int getStatusBarHeight() {
int statusBarHeight = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = getResources().getDimensionPixelSize(resourceId);
}
return statusBarHeight;
}
这将导致所有API版本和不同类型的设备(手机和平板电脑)的可用显示的高度和宽度,不包括任何类型的栏(状态栏、导航栏)。
以下是低于/高于API 30代码的Kotlin扩展函数:
fun Activity.getScreenWidth(): Int {
return if (Build.VERSION.SDK_INT < 30) {
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
displayMetrics.widthPixels
} else {
val metrics = windowManager.currentWindowMetrics
val insets = metrics.windowInsets
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
metrics.bounds.width() - insets.left - insets.right
}
}
fun Activity.getScreenHeight(): Int {
return if (Build.VERSION.SDK_INT < 30) {
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
displayMetrics.heightPixels
} else {
val metrics = windowManager.currentWindowMetrics
val insets = metrics.windowInsets
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars())
metrics.bounds.height() - insets.top - insets.bottom
}
}
对应的Java助手方法:
public int getScreenWidth(Activity activity) {
if (Build.VERSION.SDK_INT < 30) {
DisplayMetrics displayMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.widthPixels;
} else {
WindowMetrics metrics = activity.getWindowManager().getCurrentWindowMetrics();
Insets insets = metrics.getWindowInsets()
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars());
return metrics.getBounds().width() - insets.left - insets.right;
}
}
public int getScreenHeight(Activity activity) {
if (Build.VERSION.SDK_INT < 30) {
DisplayMetrics displayMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels;
} else {
WindowMetrics metrics = activity.getWindowManager().getCurrentWindowMetrics();
Insets insets = metrics.getWindowInsets()
.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars());
return metrics.getBounds().height() - insets.bottom - insets.top;
}
}