DevCheck-lib/DisplayInfo屏幕尺寸使用示例.md
2025-12-29 11:39:18 +08:00

15 KiB
Raw Blame History

DisplayInfo 屏幕尺寸功能使用示例

新增功能说明

DisplayInfo 类新增了获取屏幕物理尺寸的功能,支持以下单位:

  • 英寸 (inches): 国际通用的屏幕尺寸单位
  • 毫米 (mm): 公制单位,更精确的物理尺寸

可以获取:

  • 对角线尺寸(屏幕大小)
  • 宽度尺寸
  • 高度尺寸

核心数据类

ScreenSize

data class ScreenSize(
    val diagonalInches: Double,    // 对角线尺寸(英寸)
    val diagonalMm: Double,        // 对角线尺寸(毫米)
    val widthInches: Double,       // 宽度(英寸)
    val widthMm: Double,           // 宽度(毫米)
    val heightInches: Double,      // 高度(英寸)
    val heightMm: Double           // 高度(毫米)
)

DefaultDisplayInfo (已更新)

现在包含 screenSize: ScreenSize 字段,提供完整的屏幕物理尺寸信息。

使用示例

1. 获取完整的屏幕尺寸信息

val displayInfo = DisplayInfo(context)

// 获取完整的屏幕尺寸信息
val screenSize = displayInfo.getScreenSize()

screenSize?.let {
    println("=== Screen Size ===")
    println("Diagonal: ${String.format("%.2f", it.diagonalInches)}\" (${String.format("%.1f", it.diagonalMm)} mm)")
    println("Width: ${String.format("%.2f", it.widthInches)}\" (${String.format("%.1f", it.widthMm)} mm)")
    println("Height: ${String.format("%.2f", it.heightInches)}\" (${String.format("%.1f", it.heightMm)} mm)")
}

输出示例:

=== Screen Size ===
Diagonal: 6.67" (169.4 mm)
Width: 2.91" (73.9 mm)
Height: 6.32" (160.5 mm)

2. 获取屏幕对角线尺寸

val displayInfo = DisplayInfo(context)

// 获取对角线尺寸(英寸)
val diagonalInches = displayInfo.getScreenDiagonalInches()
println("Screen Size: ${String.format("%.2f", diagonalInches)}\"")

// 获取对角线尺寸(毫米)
val diagonalMm = displayInfo.getScreenDiagonalMm()
println("Screen Size: ${String.format("%.1f", diagonalMm)} mm")

输出示例:

Screen Size: 6.67"
Screen Size: 169.4 mm

3. 获取屏幕宽度和高度

val displayInfo = DisplayInfo(context)

// 获取宽度
val widthInches = displayInfo.getScreenWidthInches()
val widthMm = displayInfo.getScreenWidthMm()
println("Screen Width: ${String.format("%.2f", widthInches)}\" / ${String.format("%.1f", widthMm)} mm")

// 获取高度
val heightInches = displayInfo.getScreenHeightInches()
val heightMm = displayInfo.getScreenHeightMm()
println("Screen Height: ${String.format("%.2f", heightInches)}\" / ${String.format("%.1f", heightMm)} mm")

输出示例:

Screen Width: 2.91" / 73.9 mm
Screen Height: 6.32" / 160.5 mm

4. 从 DefaultDisplayInfo 获取完整信息

val displayInfo = DisplayInfo(context)

val defaultDisplayInfo = displayInfo.getDefaultDisplayInfo()

defaultDisplayInfo?.let { info ->
    println("=== Display Information ===")
    println("Name: ${info.name}")
    println("Resolution: ${info.widthPixels} x ${info.heightPixels}")
    println("Density: ${info.densityDpi} dpi")
    println("PPI: ${String.format("%.1f", info.ppi)}")
    println("Refresh Rate: ${info.refreshRate} Hz")
    
    // 屏幕尺寸
    println("\n=== Screen Size ===")
    println("Diagonal: ${String.format("%.2f", info.screenSize.diagonalInches)}\"")
    println("Size: ${String.format("%.2f", info.screenSize.widthInches)}\" x ${String.format("%.2f", info.screenSize.heightInches)}\"")
    println("Size (mm): ${String.format("%.1f", info.screenSize.widthMm)} x ${String.format("%.1f", info.screenSize.heightMm)} mm")
    
    // HDR 信息
    if (info.isHdr) {
        println("\n=== HDR Support ===")
        println("HDR Types: ${info.hdrTypes.joinToString(", ")}")
    }
    
    // 广色域
    if (info.isWideColorGamut) {
        println("Wide Color Gamut: Supported")
    }
}

输出示例:

=== Display Information ===
Name: Built-in Screen
Resolution: 1080 x 2400
Density: 393 dpi
PPI: 395.6
Refresh Rate: 120.0 Hz

=== Screen Size ===
Diagonal: 6.67"
Size: 2.91" x 6.32"
Size (mm): 73.9 x 160.5 mm

=== HDR Support ===
HDR Types: HDR10, HDR10+

Wide Color Gamut: Supported

5. 计算屏幕纵横比

val displayInfo = DisplayInfo(context)

val screenSize = displayInfo.getScreenSize()

screenSize?.let {
    // 计算纵横比
    val aspectRatio = it.widthInches / it.heightInches
    
    // 判断常见纵横比
    val ratioName = when {
        aspectRatio.isCloseTo(9.0 / 16.0, 0.01) -> "16:9"
        aspectRatio.isCloseTo(9.0 / 18.0, 0.01) -> "18:9 (2:1)"
        aspectRatio.isCloseTo(9.0 / 19.5, 0.01) -> "19.5:9"
        aspectRatio.isCloseTo(9.0 / 20.0, 0.01) -> "20:9"
        aspectRatio.isCloseTo(9.0 / 21.0, 0.01) -> "21:9"
        aspectRatio.isCloseTo(3.0 / 4.0, 0.01) -> "4:3"
        else -> String.format("%.2f:1", 1.0 / aspectRatio)
    }
    
    println("Screen Aspect Ratio: $ratioName")
}

// 辅助函数
fun Double.isCloseTo(target: Double, tolerance: Double): Boolean {
    return kotlin.math.abs(this - target) < tolerance
}

6. 计算屏幕面积

val displayInfo = DisplayInfo(context)

val screenSize = displayInfo.getScreenSize()

screenSize?.let {
    // 计算面积(平方英寸)
    val areaInches = it.widthInches * it.heightInches
    
    // 计算面积(平方厘米)
    val areaCm = (it.widthMm / 10.0) * (it.heightMm / 10.0)
    
    println("Screen Area: ${String.format("%.2f", areaInches)} in²")
    println("Screen Area: ${String.format("%.2f", areaCm)} cm²")
}

输出示例:

Screen Area: 18.39 in²
Screen Area: 118.65 cm²

7. 在 Jetpack Compose 中显示

@Composable
fun ScreenSizeCard() {
    val context = LocalContext.current
    val displayInfo = remember { DisplayInfo(context) }
    val defaultDisplayInfo = remember { displayInfo.getDefaultDisplayInfo() }
    
    defaultDisplayInfo?.let { info ->
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp),
            elevation = CardDefaults.cardElevation(4.dp)
        ) {
            Column(modifier = Modifier.padding(16.dp)) {
                Text(
                    text = "Display Information",
                    style = MaterialTheme.typography.titleLarge,
                    fontWeight = FontWeight.Bold
                )
                
                Spacer(modifier = Modifier.height(16.dp))
                
                // 分辨率和密度
                InfoSection(title = "Resolution & Density") {
                    InfoRow("Resolution", "${info.widthPixels} x ${info.heightPixels} px")
                    InfoRow("Density", "${info.densityDpi} dpi")
                    InfoRow("PPI", String.format("%.1f", info.ppi))
                }
                
                Spacer(modifier = Modifier.height(12.dp))
                
                // 屏幕尺寸
                InfoSection(title = "Screen Size") {
                    InfoRow(
                        "Diagonal",
                        String.format("%.2f\" (%.1f mm)", 
                            info.screenSize.diagonalInches,
                            info.screenSize.diagonalMm
                        )
                    )
                    InfoRow(
                        "Width",
                        String.format("%.2f\" (%.1f mm)",
                            info.screenSize.widthInches,
                            info.screenSize.widthMm
                        )
                    )
                    InfoRow(
                        "Height",
                        String.format("%.2f\" (%.1f mm)",
                            info.screenSize.heightInches,
                            info.screenSize.heightMm
                        )
                    )
                }
                
                Spacer(modifier = Modifier.height(12.dp))
                
                // 刷新率
                InfoSection(title = "Refresh Rate") {
                    InfoRow("Current", "${info.refreshRate.toInt()} Hz")
                    if (info.supportedRefreshRates.size > 1) {
                        InfoRow(
                            "Supported",
                            info.supportedRefreshRates.joinToString(", ") { "${it.toInt()} Hz" }
                        )
                    }
                }
                
                // HDR 和色域
                if (info.isHdr || info.isWideColorGamut) {
                    Spacer(modifier = Modifier.height(12.dp))
                    
                    InfoSection(title = "Advanced Features") {
                        if (info.isHdr) {
                            InfoRow("HDR", info.hdrTypes.joinToString(", "))
                        }
                        if (info.isWideColorGamut) {
                            InfoRow("Color Gamut", "Wide Color Gamut")
                        }
                    }
                }
            }
        }
    }
}

@Composable
fun InfoSection(title: String, content: @Composable () -> Unit) {
    Column {
        Text(
            text = title,
            style = MaterialTheme.typography.titleMedium,
            fontWeight = FontWeight.SemiBold,
            color = MaterialTheme.colorScheme.primary
        )
        Spacer(modifier = Modifier.height(8.dp))
        content()
    }
}

@Composable
fun InfoRow(label: String, value: String) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 4.dp),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(
            text = label,
            style = MaterialTheme.typography.bodyMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )
        Text(
            text = value,
            style = MaterialTheme.typography.bodyMedium,
            fontWeight = FontWeight.Medium,
            textAlign = TextAlign.End,
            modifier = Modifier.weight(1f, fill = false)
        )
    }
}

8. 比较设备屏幕大小

fun compareScreenSizes(context: Context) {
    val displayInfo = DisplayInfo(context)
    val screenSize = displayInfo.getScreenSize() ?: return
    
    println("=== Screen Size Comparison ===")
    
    val diagonal = screenSize.diagonalInches
    
    val category = when {
        diagonal < 4.5 -> "Compact Phone (< 4.5\")"
        diagonal < 5.5 -> "Standard Phone (4.5\" - 5.5\")"
        diagonal < 6.5 -> "Large Phone (5.5\" - 6.5\")"
        diagonal < 7.5 -> "Phablet (6.5\" - 7.5\")"
        diagonal < 10.0 -> "Small Tablet (7.5\" - 10\")"
        diagonal < 13.0 -> "Standard Tablet (10\" - 13\")"
        else -> "Large Tablet (> 13\")"
    }
    
    println("Device Category: $category")
    println("Screen Diagonal: ${String.format("%.2f", diagonal)}\"")
    
    // 与常见设备比较
    println("\nComparison with common sizes:")
    println("iPhone 15 Pro Max: ~6.7\"")
    println("Samsung Galaxy S24 Ultra: ~6.8\"")
    println("iPad Pro 11\": ~11\"")
    println("iPad Pro 12.9\": ~12.9\"")
}

9. 计算最佳查看距离

fun calculateOptimalViewingDistance(context: Context) {
    val displayInfo = DisplayInfo(context)
    val defaultInfo = displayInfo.getDefaultDisplayInfo() ?: return
    
    // 基于 PPI 和屏幕尺寸计算最佳查看距离
    // 一般建议:对于 300+ PPI最佳查看距离约为屏幕对角线的 1.5-2 倍
    
    val diagonalInches = defaultInfo.screenSize.diagonalInches
    val ppi = defaultInfo.ppi
    
    val minDistance = diagonalInches * 1.5
    val maxDistance = diagonalInches * 2.0
    
    // 转换为厘米
    val minDistanceCm = minDistance * 2.54
    val maxDistanceCm = maxDistance * 2.54
    
    println("=== Optimal Viewing Distance ===")
    println("Screen: ${String.format("%.2f", diagonalInches)}\" @ ${String.format("%.0f", ppi)} PPI")
    println("Recommended distance: ${String.format("%.1f", minDistanceCm)} - ${String.format("%.1f", maxDistanceCm)} cm")
    println("                     (${String.format("%.1f", minDistance)} - ${String.format("%.1f", maxDistance)} inches)")
}

10. 检测屏幕类型

fun detectScreenType(context: Context): String {
    val displayInfo = DisplayInfo(context)
    val defaultInfo = displayInfo.getDefaultDisplayInfo() ?: return "Unknown"
    
    val diagonal = defaultInfo.screenSize.diagonalInches
    val widthPixels = defaultInfo.widthPixels
    val heightPixels = defaultInfo.heightPixels
    val ppi = defaultInfo.ppi
    
    // 计算纵横比
    val aspectRatio = widthPixels.toDouble() / heightPixels.toDouble()
    
    return buildString {
        // 设备类型
        append(when {
            diagonal < 7.0 -> "Smartphone"
            diagonal < 10.0 -> "Phablet/Small Tablet"
            else -> "Tablet"
        })
        
        append(" | ")
        
        // 屏幕质量
        append(when {
            ppi >= 500 -> "Ultra High Density"
            ppi >= 400 -> "Very High Density"
            ppi >= 300 -> "High Density"
            ppi >= 200 -> "Medium Density"
            else -> "Low Density"
        })
        
        append(" | ")
        
        // 纵横比类型
        append(when {
            aspectRatio < 0.5 -> "Ultra-wide (21:9+)"
            aspectRatio < 0.52 -> "Wide (20:9)"
            aspectRatio < 0.54 -> "Wide (19.5:9)"
            aspectRatio < 0.58 -> "Standard (18:9)"
            aspectRatio < 0.60 -> "Standard (16:9)"
            else -> "Traditional (4:3)"
        })
    }
}

// 使用示例
val screenType = detectScreenType(context)
println("Screen Type: $screenType")
// 输出: "Smartphone | Very High Density | Wide (20:9)"

技术细节

计算方法

  1. 对角线尺寸

    diagonal_inches = √(width_inches² + height_inches²)
    
  2. 宽度/高度转换

    width_inches = width_pixels / xdpi
    height_inches = height_pixels / ydpi
    
  3. 英寸到毫米转换

    millimeters = inches × 25.4
    

精确度说明

  • 计算基于设备报告的 xdpiydpi
  • 大多数设备提供准确的 DPI 信息
  • 某些低端设备可能报告不准确的 DPI导致尺寸计算偏差
  • 对角线尺寸通常误差在 ±0.1 英寸以内

注意事项

  1. DPI 准确性:计算依赖于系统报告的 DPI 值,大多数现代设备提供准确的值

  2. 单位转换

    • 1 英寸 = 25.4 毫米
    • 1 英寸 = 2.54 厘米
  3. 屏幕对角线:通常所说的屏幕尺寸指的是对角线长度(如 6.7 英寸手机)

  4. 无需权限:获取屏幕尺寸信息不需要任何特殊权限

  5. 兼容性:支持所有 Android 版本,使用标准 Android API

  6. 性能:计算是轻量级的,可以频繁调用而不影响性能

常见屏幕尺寸参考

智能手机

  • 紧凑型: 4.0" - 5.0"
  • 标准型: 5.0" - 6.0"
  • 大屏型: 6.0" - 6.5"
  • 超大屏: 6.5" - 7.0"

平板电脑

  • 小型平板: 7" - 8"
  • 标准平板: 9" - 10"
  • 大型平板: 11" - 13"

物理尺寸示例

  • iPhone 15 Pro Max: 6.7" (约 170 mm)
  • Samsung Galaxy S24 Ultra: 6.8" (约 173 mm)
  • iPad Air: 10.9" (约 277 mm)
  • iPad Pro: 12.9" (约 328 mm)

扩展用途

屏幕尺寸信息可以用于:

  • UI 布局自适应
  • 字体大小调整
  • 图片资源选择
  • 视频播放优化
  • 游戏控制布局
  • 阅读体验优化
  • 设备分类统计
  • 用户体验研究