【问题标题】:Getting screen size not from Activity subclass不是从 Activity 子类获取屏幕大小
【发布时间】:2012-07-25 01:27:28
【问题描述】:

我有一个从像这样的活动子类开始的视图子类:

this.setContentView(instanceOfMyView);

在我的视图子类中,我想对屏幕尺寸进行一些处理,但这里的所有人都说应该像这样开始:

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm); 
screenWidth = dm.widthPixels;
screenHeight = dm.heightPixels; 

但是getWindowManager() 是只能从活动子类调用的方法(对吗?)

那么,这是个坏主意,我需要在活动中获取屏幕尺寸并将其用作视图构造函数中的参数,还是有办法在视图子类中获取屏幕尺寸?也许,只需要以某种方式获取视图类中活动实例的链接?

提前致谢。

【问题讨论】:

    标签: android android-activity android-view screen-size


    【解决方案1】:

    是的,有一种方法,如果你可以将上下文对象传递给你的非活动类,

       int width= context.getResources().getDisplayMetrics().widthPixels;
       int height= context.getResources().getDisplayMetrics().heightPixels;
    

    您不需要活动对象本身。

    【讨论】:

    • 完美,我已经在视图子类的构造函数中有context 对象。谢谢。
    • 这不会返回屏幕分辨率。只有减去各种系统栏后才可用
    【解决方案2】:
    DisplayMetrics metrics = getBaseContext().getResources().getDisplayMetrics();         
        final int w = metrics.widthPixels;
        final int h = metrics.heightPixels;
    

    【讨论】:

    • 似乎getBaseContext() 在视图子类中不起作用,而只是getContext() 起作用。
    • 这不会返回屏幕分辨率。只有减去各种系统栏后才可用
    【解决方案3】:

    这里的其他答案不会给你屏幕分辨率。

    你应该这样做:

    @SuppressLint("ObsoleteSdkInt")
    @JvmStatic
    fun getScreenResolution(context: Context, naturalResolution: Boolean = false): Point {
        val screenResolution = Point()
        val display = getDisplay(context)!!
        @Suppress("DEPRECATION")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            display.getRealSize(screenResolution)
        } else display.getSize(screenResolution)
        if (naturalResolution) {
            val screenNaturalOrientation = getScreenNaturalOrientation(context)
            if ((screenNaturalOrientation == Configuration.ORIENTATION_PORTRAIT && screenResolution.x > screenResolution.y)
                    || (screenNaturalOrientation == Configuration.ORIENTATION_LANDSCAPE && screenResolution.y > screenResolution.x))
                screenResolution.set(screenResolution.y, screenResolution.x)
        }
        return screenResolution
    }
    
    /**
     * returns the natural orientation of the device: Configuration.ORIENTATION_LANDSCAPE or Configuration.ORIENTATION_PORTRAIT .<br></br>
     * The result should be consistent no matter the orientation of the device
     */
    fun getScreenNaturalOrientation(context: Context): Int {
        //based on : http://stackoverflow.com/a/9888357/878126
        val config = context.resources.configuration
        val rotation = getDisplay(context)!!.rotation
        return if ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
                config.orientation == Configuration.ORIENTATION_LANDSCAPE
                || (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
                config.orientation == Configuration.ORIENTATION_PORTRAIT) Configuration.ORIENTATION_LANDSCAPE else Configuration.ORIENTATION_PORTRAIT
    }
    

    要获得显示,请使用:

    fun getDisplay(context: Context): Display? {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
            try {
                val result = context.display
                if (result != null)
                    return result
            } catch (e: Throwable) {
            }
        if (context is Activity) {
            return try {
                @Suppress("DEPRECATION")
                context.windowManager.defaultDisplay
            } catch (e: Throwable) {
                null
            }
        }
        return null
    }
    

    文档:

    https://developer.android.com/reference/android/view/Display.html#getRealSize(android.graphics.Point)

    【讨论】:

    • 从 API 30 开始,WindowManager#getDefaultDisplay() 已弃用。获取与 WindowManager 关联的显示的新预期方法是什么?上下文必须是活动上下文,还是可以是应用程序上下文?
    • 另外,getRealSize() 对设备方向敏感。我们如何才能获得纵向模式或设备自然方向的真实宽度/高度?
    • @pallgeuer 是一个相当古老的解决方案。我现在已经更新了。如果它现在似乎运作良好,请告诉我。
    • 我在我的项目中使用 java,但我详细检查了更新的 kotlin 代码,它似乎是正确的,谢谢。要回答我上面自己的问题,使用应用程序上下文可以工作,但这不是有意的,如果你这样做,StrictMode 会给你一个红色的警告(getDisplay() from an non-visual context in java)。
    • 自然分辨率位不能只是 (?):if(naturalResolution) { val rotation = getDisplay(context)!!.rotation if(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) screenResolution.set(screenResolution.y, screenResolution.x) } 但是在实用程序带中也有 getScreenNaturalOrientation 功能真是太好了。
    【解决方案4】:

    这可以在任何类中使用:

    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    Integer with = metrics.widthPixels;
    Integer height = metrics.heightPixels;
    

    希望有帮助

    【讨论】:

      【解决方案5】:

      比公认的答案还要简单。你不需要上下文。

      object ScreenUtils {
      
          fun getScreenWidth() = Resources.getSystem().displayMetrics.widthPixels
      
          fun getScreenHeight() = Resources.getSystem().displayMetrics.heightPixels
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-02
        • 1970-01-01
        相关资源
        最近更新 更多