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

524 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DisplayInfo 屏幕尺寸功能使用示例
## 新增功能说明
`DisplayInfo` 类新增了获取屏幕物理尺寸的功能,支持以下单位:
- **英寸 (inches)**: 国际通用的屏幕尺寸单位
- **毫米 (mm)**: 公制单位,更精确的物理尺寸
可以获取:
- 对角线尺寸(屏幕大小)
- 宽度尺寸
- 高度尺寸
## 核心数据类
### ScreenSize
```kotlin
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. 获取完整的屏幕尺寸信息
```kotlin
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. 获取屏幕对角线尺寸
```kotlin
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. 获取屏幕宽度和高度
```kotlin
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 获取完整信息
```kotlin
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. 计算屏幕纵横比
```kotlin
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. 计算屏幕面积
```kotlin
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 中显示
```kotlin
@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. 比较设备屏幕大小
```kotlin
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. 计算最佳查看距离
```kotlin
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. 检测屏幕类型
```kotlin
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
```
### 精确度说明
- 计算基于设备报告的 `xdpi``ydpi`
- 大多数设备提供准确的 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 布局自适应
- 字体大小调整
- 图片资源选择
- 视频播放优化
- 游戏控制布局
- 阅读体验优化
- 设备分类统计
- 用户体验研究