Get screen dimensions in pixels
我创建了一些自定义元素,我想以编程方式将它们放置在右上角(
1 2 | int px = screenWidth - m; int py = screenHeight - n; |
如何在主Activity中获得
如果您想要显示尺寸(以像素为单位),可以使用
1 2 3 4 5 | Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); int width = size.x; int height = size.y; |
如果您不在
1 2 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); |
如果你在一个片段中想要完成它,只需使用Activity.WindowManager(在Xamarin.Android中)或getActivity()。getWindowManager()(在java中)。
在引入
1 2 3 | Display display = getWindowManager().getDefaultDisplay(); int width = display.getWidth(); // deprecated int height = display.getHeight(); // deprecated |
但是,对于您正在描述的用例,布局中的边距/填充似乎更合适。
另一种方法是:DisplayMetrics
A structure describing general information about a display, such as its size, density, and font scaling. To access the DisplayMetrics members, initialize an object like this:
1 2 | DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); |
我们可以使用
"The absolute width of the display in pixels."
例:
1 | Log.d("ApplicationTagName","Display width in px is" + metrics.widthPixels); |
一种方法是:
1 2 3 | Display display = getWindowManager().getDefaultDisplay(); int width = display.getWidth(); int height = display.getHeight(); |
它已弃用,您应该尝试使用以下代码。前两行代码为您提供
1 2 3 4 5 | DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int height = metrics.heightPixels; int width = metrics.widthPixels; |
它可能无法回答你的问题,但知道(当我提出这个问题时我自己正在寻找它)可能是有用的,如果你需要一个View的维度,但你的代码在布局尚未布局时正在执行(例如在
(2012年回答,可能已过时)如果你想支持precomb,你需要在API 13之前提供向后兼容性。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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的用户,这就是我们留下的。
我尝试了所有可能的"解决方案"并没有成功,我注意到Elliott Hughes的"Dalvik Explorer"应用程序总是在任何Android设备/操作系统版本上显示正确的尺寸。我最后看了他的开源项目,可以在这里找到:https://code.google.com/p/enh/
这是所有相关代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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) { } |
编辑:稍微改进版本(避免在不支持的操作系统版本上触发异常):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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) { } |
最简单的方法:
1 2 | int screenHeight = getResources().getDisplayMetrics().heightPixels; int screenWidth = getResources().getDisplayMetrics().widthPixels; |
要访问Android设备状态栏的高度,我们更喜欢以编程方式获取它:
示例代码
1 2 3 4 | int resId = getResources().getIdentifier("status_bar_height","dimen","android"); if (resId > 0) { result = getResources().getDimensionPixelSize(resId); } |
变量
快速访问
有关
首先获取视图(例如,通过
我有两个函数,一个用于发送上下文,另一个用于获取高度和宽度(以像素为单位):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } |
和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } |
这是我用于任务的代码:
1 2 3 4 5 6 7 8 9 | // `activity` is an instance of Activity class. Display display = activity.getWindowManager().getDefaultDisplay(); Point screen = new Point(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { display.getSize(screen); } else { screen.x = display.getWidth(); screen.y = display.getHeight(); } |
看起来足够干净但是,请注意弃用。
这不是一个更好的解决方案吗? DisplayMetrics提供您需要的一切,并且可以在API 1中使用。
1 2 3 4 5 6 7 8 9 | public void getScreenInfo(){ DisplayMetrics metrics = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics); heightPixels = metrics.heightPixels; widthPixels = metrics.widthPixels; density = metrics.density; densityDpi = metrics.densityDpi; } |
您还可以使用getRealMetrics获取实际显示(包括屏幕装饰,例如状态栏或软件导航栏),但这仅适用于17+。
我错过了什么吗?
对于使用XML动态扩展,有一个名为"android:layout_weight"的属性
以下示例,根据synic在此线程上的响应进行修改,显示占据屏幕75%(重量= .25)的按钮,以及占据屏幕剩余25%(重量= .75)的文本视图。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight=".25" android:text="somebutton"> <TextView android:layout_width="fill_parent" android:layout_height="Wrap_content" android:layout_weight=".75"> </LinearLayout> |
找到屏幕的宽度和高度:
1 2 | width = getWindowManager().getDefaultDisplay().getWidth(); height = getWindowManager().getDefaultDisplay().getHeight(); |
使用此功能,我们可以获得最新及以上的SDK 13。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // New width and height int version = android.os.Build.VERSION.SDK_INT; Log.i(""," name =="+ version); Display display = getWindowManager().getDefaultDisplay(); int width; if (version >= 13) { Point size = new Point(); display.getSize(size); width = size.x; Log.i("width","if =>" +width); } else { width = display.getWidth(); Log.i("width","else =>" +width); } |
只是添加到Francesco的答案。另一个更贴切的观察者,如果你想找到窗口中的位置或屏幕中的位置是
ViewTreeObserver.OnPreDrawListener()
这也可用于查找onCreate()时间内大部分未知的视图的其他属性,例如滚动位置,缩放位置。
1 2 3 4 | DisplayMetrics dimension = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dimension); int w = dimension.widthPixels; int h = dimension.heightPixels; |
在Activity中使用以下代码。
1 2 3 4 | DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int height = metrics.heightPixels; int wwidth = metrics.widthPixels; |
需要说明的是,如果您不在
第一:
1 | DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics(); |
第二:
1 2 | DisplayMetrics dm = new DisplayMetrics(); yourView.getDisplay().getMetrics(dm); |
我们在这里调用的所有方法都不会被弃用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class AndroidScreenActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); String str_ScreenSize ="The Android Screen is:" + dm.widthPixels +" x" + dm.heightPixels; TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize); mScreenSize.setText(str_ScreenSize); } } |
我发现这就行了。
1 2 | Rect dim = new Rect(); getWindowVisibleDisplayFrame(dim); |
要获取屏幕尺寸,请使用显示矩阵
1 2 3 4 5 6 | DisplayMetrics displayMetrics = new DisplayMetrics(); if (context != null) WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display defaultDisplay = windowManager.getDefaultDisplay(); defaultDisplay.getRealMetrics(displayMetrics); } |
获取高度和宽度(以像素为单位)
1 2 | int width =displayMetrics.widthPixels; int height =displayMetrics.heightPixels; |
这不是OP的答案,因为他想要实际像素的显示尺寸。我想要"与设备无关的像素"中的维度,并从这里汇总答案https://stackoverflow.com/a/17880012/253938和这里https://stackoverflow.com/a/6656774/253938我出现了有了这个:
1 2 3 | DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics(); int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5); int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5); |
我会像这样包装getSize代码:
1 2 3 4 5 6 7 8 9 10 11 12 | @SuppressLint("NewApi") public static Point getScreenSize(Activity a) { Point size = new Point(); Display d = a.getWindowManager().getDefaultDisplay(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { d.getSize(size); } else { size.x = d.getWidth(); size.y = d.getHeight(); } return size; } |
你可以使用以下方法获得身高:
1 | getResources().getDisplayMetrics().heightPixels; |
和宽度大小使用
1 | getResources().getDisplayMetrics().widthPixels; |
使用DisplayMetrics(API 1)有一种不推荐的方法可以避免try / catch杂乱:
1 2 3 4 5 6 7 8 9 | // initialize the DisplayMetrics object DisplayMetrics deviceDisplayMetrics = new DisplayMetrics(); // populate the DisplayMetrics object with the display characteristics getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics); // get the width and height screenWidth = deviceDisplayMetrics.widthPixels; screenHeight = deviceDisplayMetrics.heightPixels; |
对于谁在没有状态栏和操作栏的情况下搜索可用的屏幕尺寸(也感谢Swapnil的回答):
1 2 3 4 5 6 7 8 9 10 11 12 13 | DisplayMetrics dm = getResources().getDisplayMetrics(); float screen_w = dm.widthPixels; float screen_h = dm.heightPixels; int resId = getResources().getIdentifier("status_bar_height","dimen","android"); if (resId > 0) { screen_h -= getResources().getDimensionPixelSize(resId); } TypedValue typedValue = new TypedValue(); if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){ screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId); } |
首先加载XML文件,然后编写以下代码:
1 2 3 4 | setContentView(R.layout.main); Display display = getWindowManager().getDefaultDisplay(); final int width = (display.getWidth()); final int height = (display.getHeight()); |
根据屏幕分辨率显示宽度和高度。
请遵循以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public static int getWidthScreen(Context context) { return getDisplayMetrics(context).widthPixels; } public static int getHeightScreen(Context context) { return getDisplayMetrics(context).heightPixels; } private static DisplayMetrics getDisplayMetrics(Context context) { DisplayMetrics displayMetrics = new DisplayMetrics(); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); wm.getDefaultDisplay().getMetrics(displayMetrics); return displayMetrics; } |
如果您不需要WindowManagers,Points或Displays的开销,则可以获取XML中最顶层View项的height和width属性,前提是它的高度和宽度设置为match_parent。 (只要您的布局占用整个屏幕,这都是正确的。)
例如,如果您的XML以这样的内容开头:
1 2 3 4 5 6 | <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/entireLayout" android:layout_width="match_parent" android:layout_height="match_parent"> |
然后
在活动的onCreate中,有时您需要知道布局的可用空间的精确尺寸。
经过一番思考后,我就这样做了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); startActivityForResult(new Intent(this, Measure.class), 1); // Return without setting the layout, that will be done in onActivityResult. } @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { // Probably can never happen, but just in case. if (resultCode == RESULT_CANCELED) { finish(); return; } int width = data.getIntExtra("Width", -1); // Width is now set to the precise available width, and a layout can now be created. ... } } public final class Measure extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a LinearLayout with a MeasureFrameLayout in it. // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way. LinearLayout linearLayout = new LinearLayout(this); LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this); measureFrameLayout.setLayoutParams(matchParent); linearLayout.addView(measureFrameLayout); this.addContentView(linearLayout, matchParent); // measureFrameLayout will now request this second activity to finish, sending back the width. } class MeasureFrameLayout extends FrameLayout { boolean finished = false; public MeasureFrameLayout(Context context) { super(context); } @SuppressLint("DrawAllocation") @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (finished) { return; } finished = true; // Send the width back as the result. Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec)); Measure.this.setResult(Activity.RESULT_OK, data); // Tell this activity to finish, so the result is passed back. Measure.this.finish(); } } } |
如果由于某种原因您不想在Android清单中添加其他活动,则可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | public class MainActivity extends Activity { static Activity measuringActivity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle extras = getIntent().getExtras(); if (extras == null) { extras = new Bundle(); } int width = extras.getInt("Width", -2); if (width == -2) { // First time in, just start another copy of this activity. extras.putInt("Width", -1); startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1); // Return without setting the layout, that will be done in onActivityResult. return; } if (width == -1) { // Second time in, here is where the measurement takes place. // Create a LinearLayout with a MeasureFrameLayout in it. // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way. LinearLayout linearLayout = new LinearLayout(measuringActivity = this); LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this); measureFrameLayout.setLayoutParams(matchParent); linearLayout.addView(measureFrameLayout); this.addContentView(linearLayout, matchParent); // measureFrameLayout will now request this second activity to finish, sending back the width. } } @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { // Probably can never happen, but just in case. if (resultCode == RESULT_CANCELED) { finish(); return; } int width = data.getIntExtra("Width", -3); // Width is now set to the precise available width, and a layout can now be created. ... } class MeasureFrameLayout extends FrameLayout { boolean finished = false; public MeasureFrameLayout(Context context) { super(context); } @SuppressLint("DrawAllocation") @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (finished) { return; } finished = true; // Send the width back as the result. Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec)); MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data); // Tell the (second) activity to finish. MainActivity.measuringActivity.finish(); } } |
我有一个启动画面活动,其中LinearLayout作为根视图,其宽度和宽度都有match_parent;高度。这是该活动的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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); } }); } |
以下是您在上面看到的方法的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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版本和不同类型的设备(手机和平板电脑)。
科特林
1 2 3 4 5 6 7 8 9 10 11 | fun getScreenHeight(activity: Activity): Int { val metrics = DisplayMetrics() activity.windowManager.defaultDisplay.getMetrics(metrics) return metrics.heightPixels } fun getScreenWidth(activity: Activity): Int { val metrics = DisplayMetrics() activity.windowManager.defaultDisplay.getMetrics(metrics) return metrics.widthPixels } |
如果Display类不起作用,则上面的答案将无效,那么您可以通过以下方法获得宽度和高度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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; } |
简单的功能也兼容较低版本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * @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()}; } } |
使用:
1 2 | int width = getScreenSize()[0]; int height = getScreenSize()[1]; |
此函数返回以英寸为单位的近似屏幕尺寸。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public double getScreenSize() { DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int width=dm.widthPixels; int height=dm.heightPixels; int dens=dm.densityDpi; double wi=(double)width/(double)dens; double hi=(double)height/(double)dens; double x = Math.pow(wi,2); double y = Math.pow(hi,2); double screenInches = Math.sqrt(x+y); return screenInches; } |
以下是Kotlin实现中上述一些答案的简单改编。如上所述,它需要清单中的windowsSoftInput ="adjustResize":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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) } } |
并使用:
1 2 3 4 | val activityRootView = findViewById<ViewGroup>(R.id.activityRoot) KeyboardWatcher(activityRootView).observer = { visible -> if (visible) do something here ... } |
请注意,这些API返回的高度将低于设备的物理高度,因为减去了按钮栏的高度。
例如:在Moto X4上,它返回正确的widthPixels(1080)但它返回的高度为1776,即使设备的屏幕高度为1920像素。
1 2 3 | DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels; float fheight = dm.density * dm.heightPixels; |
如果
其他一些注释指的是乘以比例(密度)以获得尺寸的精确浮点值。在Android v2.2(API 8)和v4.0中测试,结果良好,没有错误/警告。
我使用了上面的提案并为我们的问题创建了一个kotlin版本。希望这为使用kotlin的人提供一些额外的帮助:
1 2 3 4 5 6 7 8 9 10 11 12 13 | private val screenDimensions: Int by lazy { val display = (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay Point() .also { size -> when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 -> display.getRealSize(size) else -> display.getSize(size) } } } screenDimensions.x // width screenDimensions.y // height |
我认为这是最简单的
1 2 3 4 5 6 7 8 9 10 11 12 | private fun checkDisplayResolution() { val displayMetrics = DisplayMetrics().also { windowManager.defaultDisplay.getMetrics(it) } Log.i(TAG,"display width: ${displayMetrics.widthPixels}") Log.i(TAG,"display height: ${displayMetrics.heightPixels}") Log.i(TAG,"display width dpi: ${displayMetrics.xdpi}") Log.i(TAG,"display height dpi: ${displayMetrics.ydpi}") Log.i(TAG,"display density: ${displayMetrics.density}") Log.i(TAG,"display scaled density: ${displayMetrics.scaledDensity}") } |