Android兼容API24+获取正确屏幕宽度问题
问题解决方法
核心原因
你遇到的宽度不匹配问题,本质是获取的"屏幕尺寸"和ImageView实际占据的窗口尺寸不一致——系统UI(如侧边导航栏、状态栏)、窗口Insets等因素会导致屏幕物理尺寸和应用窗口可用尺寸存在差异,而你的ImageView是match_parent,它的尺寸是应用窗口的实际可用尺寸,不是屏幕物理尺寸。
最优解决方案:直接获取ImageView的实际尺寸
既然你的ImageView已经和屏幕显示尺寸一致,直接拿它布局完成后的尺寸创建Bitmap是最准确的,无需绕弯获取屏幕尺寸:
// 在Activity/Fragment的合适位置调用(比如onCreate之后) yourImageView.post { val bitmapWidth = yourImageView.width val bitmapHeight = yourImageView.height val bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888) yourImageView.setImageBitmap(bitmap) }
用post的原因是:View的width和height只有在布局测量完成后才会有有效值,post会把任务放到UI消息队列,等待View布局完成后执行。
兼容API24+的窗口尺寸获取方法(如果一定要获取窗口尺寸)
如果不想依赖ImageView的尺寸,可以写一个兼容方法,直接获取应用窗口的可用区域尺寸(和ImageView的match_parent尺寸一致):
import android.app.Activity import android.os.Build import android.view.DisplayMetrics import android.view.WindowInsets fun getAppWindowSize(activity: Activity): Pair<Int, Int> { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { val windowMetrics = activity.windowManager.currentWindowMetrics // 忽略系统栏的遮挡,获取窗口可用区域 val insets = windowMetrics.windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) val usableWidth = windowMetrics.bounds.width() - insets.left - insets.right val usableHeight = windowMetrics.bounds.height() - insets.top - insets.bottom Pair(usableWidth, usableHeight) } else { val displayMetrics = DisplayMetrics() @Suppress("DEPRECATION") activity.windowManager.defaultDisplay.getMetrics(displayMetrics) // API24-29中,displayMetrics直接返回窗口可用尺寸 Pair(displayMetrics.widthPixels, displayMetrics.heightPixels) } }
调用示例:
val (width, height) = getAppWindowSize(this) val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
额外检查项
- 确认你的Activity是否设置了全屏模式,如果没有,窗口可能会被系统UI挤占部分空间:
在主题中添加:<item name="android:windowFullscreen">true</item> <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> <!-- 适配刘海屏 --> - 检查LinearLayout和ImageView是否设置了
padding或margin,如果有会导致ImageView实际显示区域小于窗口尺寸。
内容的提问来源于stack exchange,提问作者Chris B
相关产品推荐
相关产品推荐

