This commit is contained in:
grtsinry43 2025-05-11 22:50:08 +08:00
parent 9550889bdf
commit 20d9a596d7
Signed by: grtsinry43
GPG Key ID: F3305FB3A978C934
4 changed files with 2892 additions and 650 deletions

View File

@ -3,10 +3,12 @@ package com.grtsinry43.activityanalyzer
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -16,6 +18,7 @@ class MainActivity : ComponentActivity() {
} }
} }
@OptIn(ExperimentalMaterial3Api::class)
@Preview @Preview
@Composable @Composable
fun AppAndroidPreview() { fun AppAndroidPreview() {

View File

@ -1,13 +1,120 @@
package com.grtsinry43.activityanalyzer package com.grtsinry43.activityanalyzer
import androidx.compose.ui.window.Window import androidx.compose.foundation.layout.size
import androidx.compose.ui.window.application import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Analytics // 用一个合适的图标作为托盘图标
import androidx.compose.material3.Icon
import androidx.compose.runtime.*
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.toComposeImageBitmap
import androidx.compose.ui.res.loadImageBitmap
import androidx.compose.ui.res.useResource
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.*
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
fun main() = application { fun main() = application {
// 管理窗口状态,例如可见性、位置、大小
val windowState = rememberWindowState(
size = DpSize(1024.dp, 768.dp), // 设置窗口的初始大小
// position = WindowPosition(Win) // 初始位置居中
)
// 管理托盘状态
val trayState = rememberTrayState()
var isWindowVisible by remember { mutableStateOf(true) } // 控制窗口是否可见
// 尝试加载自定义托盘图标 (推荐使用 .ico 或 .png)
// 请将 "tray_icon.png" 替换为你的图标文件名,并确保它在 resources 目录下
// 如果加载失败,则使用默认图标
val trayIconPainter = try {
useResource("tray_icon.png") { stream ->
BitmapPainter(loadImageBitmap(stream))
}
} catch (e: Exception) {
println("警告:无法加载自定义托盘图标 'tray_icon.png'。将使用默认图标。错误: ${e.message}")
null // 稍后会处理 null 情况
}
// 系统托盘设置
// 只有当窗口第一次变为不可见时,或者托盘图标加载成功时,才显示托盘图标
// 这样可以避免在没有图标的情况下尝试创建托盘
if (!isWindowVisible || trayIconPainter != null) {
Tray(
state = trayState,
icon = trayIconPainter ?: BitmapPainter(createDefaultTrayIcon()), // 如果自定义图标加载失败,使用一个备用图标
tooltip = "Activity Analyzer", // 鼠标悬停在托盘图标上时显示的提示文字
menu = {
// 托盘菜单项
Item(
if (isWindowVisible) "隐藏窗口" else "显示窗口",
onClick = {
isWindowVisible = !isWindowVisible
if (isWindowVisible) {
windowState.isMinimized = false // 如果窗口被最小化了,恢复它
}
}
)
Separator() // 分隔线
Item(
"退出应用",
onClick = ::exitApplication // 点击后退出整个应用
)
}
)
}
// 主窗口设置
if (isWindowVisible) {
Window( Window(
onCloseRequest = ::exitApplication, onCloseRequest = {
// 点击关闭按钮时,可以选择隐藏到托盘而不是直接退出
isWindowVisible = false
// 或者,如果你希望点击关闭直接退出应用,则使用:
// exitApplication()
},
state = windowState, // 应用窗口状态
title = "Activity Analyzer", title = "Activity Analyzer",
resizable = true, // 允许用户调整窗口大小 (默认为 true)
// icon = painterResource("app_icon.png") // 可选:设置窗口左上角的图标和任务栏图标
) { ) {
// 在这里设置窗口的最小尺寸
// 这会影响用户能将窗口缩小到的最小程度
window.minimumSize = java.awt.Dimension(600, 400)
// 你之前创建的 DesktopApp UI
// Assuming DesktopApp is a Composable function defined elsewhere
DesktopApp() DesktopApp()
} }
}
}
// 创建一个简单的默认托盘图标 (如果自定义图标加载失败)
// 这是一个备选方案,实际项目中强烈建议使用合适的图片资源
private fun createDefaultTrayIcon(): ImageBitmap { // Change return type to ImageBitmap
// 使用 Compose 图标作为示例,实际中你应该加载一个图像文件
// 这里我们创建一个简单的 BufferedImage 代替
val width = 64
val height = 64
val image = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)
val g = image.createGraphics()
try {
// 简单绘制一个蓝色方块作为示例
g.color = java.awt.Color.BLUE
g.fillRect(0, 0, width, height)
g.color = java.awt.Color.WHITE
g.drawString("AA", 20, 40) // "Activity Analyzer" 缩写
} finally {
g.dispose()
}
// Convert BufferedImage to ImageBitmap before returning
return image.toComposeImageBitmap()
} }