15 KiB
15 KiB
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)"
技术细节
计算方法
-
对角线尺寸:
diagonal_inches = √(width_inches² + height_inches²) -
宽度/高度转换:
width_inches = width_pixels / xdpi height_inches = height_pixels / ydpi -
英寸到毫米转换:
millimeters = inches × 25.4
精确度说明
- 计算基于设备报告的
xdpi和ydpi值 - 大多数设备提供准确的 DPI 信息
- 某些低端设备可能报告不准确的 DPI,导致尺寸计算偏差
- 对角线尺寸通常误差在 ±0.1 英寸以内
注意事项
-
DPI 准确性:计算依赖于系统报告的 DPI 值,大多数现代设备提供准确的值
-
单位转换:
- 1 英寸 = 25.4 毫米
- 1 英寸 = 2.54 厘米
-
屏幕对角线:通常所说的屏幕尺寸指的是对角线长度(如 6.7 英寸手机)
-
无需权限:获取屏幕尺寸信息不需要任何特殊权限
-
兼容性:支持所有 Android 版本,使用标准 Android API
-
性能:计算是轻量级的,可以频繁调用而不影响性能
常见屏幕尺寸参考
智能手机
- 紧凑型: 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 布局自适应
- 字体大小调整
- 图片资源选择
- 视频播放优化
- 游戏控制布局
- 阅读体验优化
- 设备分类统计
- 用户体验研究