Jetpack Compose 从开门到入门之 MenuBar桌面菜单(Desktop Menu)

MenuBar是桌面版本才有的功能。也就是传统桌面应用的菜单。效果如下:
Jetpack Compose 从开门到入门之 MenuBar桌面菜单(Desktop Menu)_第1张图片
如果你写过桌面版本的Compose,在main方法里面有一个Window,MenuBar需要定义在Window里面,在别的地方是不能引用的。

@Composable
fun MyUI(){
}
fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        MenuBar(){
           //....
        }
        MyUI()
        
    }
}

下面我们将通过代码实现下面的效果。
Jetpack Compose 从开门到入门之 MenuBar桌面菜单(Desktop Menu)_第2张图片
Jetpack Compose 从开门到入门之 MenuBar桌面菜单(Desktop Menu)_第3张图片

我下了完整的代码,虽然有点长但其实非常的简单,可以直接复制执行看下效果。
主要功能就是MenuBar里面的菜单选项,以及一个用于显示点击结果的Box。

MenuBar可以定义Menu也就是一个菜单组。Menu可以定义Item也就是每一个菜单选项。

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyShortcut
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.window.MenuBar
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import com.formdev.flatlaf.FlatIntelliJLaf


@OptIn(ExperimentalComposeUiApi::class)
fun main() = application {
    var action by remember { mutableStateOf("Last action: None") }
    //菜单里面有一个exit功能,这个变量判断是否关闭应用
    var isOpen by remember { mutableStateOf(true) }

   //flatlaf是一个swing主题,可以通过在gradle中添加 implementation("com.formdev:flatlaf:2.3")使用
   // FlatIntelliJLaf.setup()


    if (isOpen) {
        var isSubmenuShowing by remember { mutableStateOf(false) }
        //onCloseRequest 一般写成这样 onCloseRequest = ::exitApplication
        //::exitApplications是系统调用,这里我们定义一个isOpen手动控制
        Window(onCloseRequest = { isOpen = false }) {

            MenuBar {
                //mnemonic表示菜单快捷键,指定后按alt+对应的键是可以快速弹出菜单的
                Menu(text = "File", mnemonic = 'F') {
                    Item(
                        text = "Copy",
                        onClick = { action = "Last action: Copy" },
                        //显示快捷键
                        shortcut = KeyShortcut(Key.C, ctrl = true)
                    )
                    Item(
                        "Paste",
                        onClick = { action = "Last action: Paste" },
                        shortcut = KeyShortcut(Key.V, ctrl = true)
                    )
                    Item(
                        "Save",
                        onClick = { action = "Last action: Save" },
                        shortcut = KeyShortcut(Key.S, ctrl = true),
                        //可以自定义设置Icon,可以指定resource目录下的图片,也可以继承Painter自己话一个
                        icon = painterResource("save.png")
                    )
                }
                Menu("Actions", mnemonic = 'A') {
                    //CheckboxItem可以做判断隐藏显示一些功能
                    CheckboxItem(
                        "Advanced settings",
                        checked = isSubmenuShowing,
                        onCheckedChange = {
                            isSubmenuShowing = !isSubmenuShowing
                        }
                    )
                    //isSubmenuShowing为真,这些菜单才出现
                    if (isSubmenuShowing) {
                        Menu("Settings") {
                            Item("Setting 1", onClick = { action = "Last action: Setting 1" })
                            Item("Setting 2", onClick = { action = "Last action: Setting 2" })
                        }
                    }
                    //菜单分割线
                    Separator()
                    //TrayIcon是一个自定义Painter,还是直接用图片比较好
                    Item("About", icon = TrayIcon, onClick = { action = "Last action: About" })
                    Item("Exit", onClick = { isOpen = false }, shortcut = KeyShortcut(Key.Escape), mnemonic = 'E')
                }
            }

            //显示哪个菜单被点击
            Box(
                modifier = Modifier.fillMaxSize(),
                contentAlignment = Alignment.Center
            ) {
                Text(text = action)
            }

        }

    }
}
//自定义Painter,还是直接用图片比较好
object TrayIcon : Painter() {
    override val intrinsicSize = Size(256f, 256f)

    override fun DrawScope.onDraw() {
        drawOval(Color(0xFFFFA500))
    }
}

菜单的主题是无法通过外面包裹一个Theme来实现更换的,默认情况下会跟随系统样式,样子就是swing默认的样子非常的丑。
Jetpack Compose 从开门到入门之 MenuBar桌面菜单(Desktop Menu)_第4张图片
可以通过添加第三方主题flatlaf来美化,Compose官方将来应该会提供自己的支持。

  implementation("com.formdev:flatlaf:2.3")

在main方法开头添加下面的代码。

FlatIntelliJLaf.setup()

效果就是文章开头的效果。

如果对你有帮助,请评论留言点赞交流。
如果对你有帮助,请评论留言点赞交流。
如果对你有帮助,请评论留言点赞交流。

你可能感兴趣的:(jetpack,compose,jetpack,compose)