前言

阅览本文需求必定compose基础,假如没有请移步Jetpack Compose入门详解(实时更新)

接口数据来源于pokeapi

项目源代码
假如你觉得不错,请给我一个star,THKS

完成作用

闲话不多说,让我们来看看完成作用

Compose Desktop 实战 宝可梦图鉴

能够看到我们完成了一个十分简洁的宝可梦图鉴,展示了一切代代的宝可梦,并提供了搜索,与宝可梦图鉴app的UI有了一些变化。


一、架构介绍

如图,展示了主要的一些文件:

Compose Desktop 实战 宝可梦图鉴

本项目没有适配安卓端,iOS端和web端(假如有乐于开源的小伙伴能够联络我),因此一切中心代码都在desktop中

  • http – 接口
  • util -东西类
  • ui -Compose组件
  • viewmodels – viewmodel

二、一些的功能点的介绍

PreCompose

经过PreCompose 这个三方库,能够像写app相同写desktop,当然这儿面有一些与app运用有些差别

import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import moe.tlaster.precompose.PreComposeWindow
import ui.FullScreenView
import util.EnvUtil
fun main() = application {
    val windowState = rememberWindowState(size = DpSize(AppConfig.windowMinWidth, AppConfig.windowMinHeight))
    PreComposeWindow(
        state = windowState,
        onCloseRequest = ::exitApplication,
        undecorated = EnvUtil.isWindows(),
        title = ""
    ) {
        //window.minimumSize = Dimension(AppConfig.windowMinWidth.value.toInt(), AppConfig.windowMinHeight.value.toInt())
        window.rootPane.apply {
            rootPane.putClientProperty("apple.awt.fullWindowContent", true)
            rootPane.putClientProperty("apple.awt.transparentTitleBar", true)
            rootPane.putClientProperty("apple.awt.windowTitleVisible", false)
        }
        FullScreenView()
        //CpnWindowsPlaformDecoratedButtons(windowState)
    }
}

PreComposeWindow便是必备的,不然后续运用一切的与PreCompose相关的都会报错 例如初始化viewmodel

import moe.tlaster.precompose.ui.viewModel
val viewModel  = viewModel { PokemonListViewModel() }

加载网络图片

桌面端加载网络图也没有安卓的原生库运用,这儿运用了compose-desktop-imageloader

package ui.common
import androidx.compose.foundation.Image 
import androidx.compose.runtime.Composable 
import androidx.compose.ui.Modifier 
import androidx.compose.ui.layout.ContentScale 
import androidx.compose.ui.res.painterResource 
import org.succlz123.lib.imageloader.ImageAsyncImageFile 
import org.succlz123.lib.imageloader.ImageAsyncImageUrl 
import org.succlz123.lib.imageloader.ImageRes 
import org.succlz123.lib.imageloader.core.ImageCallback 
@Composable
fun AsyncImage( 
    modifier: Modifier, 
    url: String?, 
    placeHolderUrl: String? = "image/ic_pokmon.jpeg", 
    errorUrl: String? = "image/ic_pokmon.jpeg", 
    contentScale: ContentScale = ContentScale.Crop 
) {
    val imgUrl = url ?: "image/ic_pokmon.jpeg" 
    if (imgUrl.startsWith("http")) { 
        ImageAsyncImageUrl(url = imgUrl, imageCallback = ImageCallback(placeHolderView = { 
            placeHolderUrl?.let { 
                Image( 
                    painter = painterResource(placeHolderUrl), 
                    contentDescription = imgUrl, 
                    modifier = modifier, 
                    contentScale = contentScale 
                )
            }
        }, errorView = { 
            errorUrl?.let { 
                Image( 
                    painter = painterResource(errorUrl), 
                    contentDescription = imgUrl, 
                    modifier = modifier, 
                    contentScale = contentScale 
                )
            }
        }) {
            Image( 
                painter = it, contentDescription = imgUrl, modifier = modifier, contentScale = contentScale 
            )
        })
    } else if (imgUrl.startsWith("/") || imgUrl.contains(":\\")) { 
        ImageAsyncImageFile(filePath = imgUrl, imageCallback = ImageCallback(placeHolderView = { 
            placeHolderUrl?.let { 
                Image( 
                    painter = painterResource(placeHolderUrl), 
                    contentDescription = imgUrl, 
                    modifier = modifier, 
                    contentScale = contentScale 
                )
            }
        }, errorView = { 
            errorUrl?.let { 
                Image( 
                    painter = painterResource(errorUrl), 
                    contentDescription = imgUrl, 
                    modifier = modifier, 
                    contentScale = contentScale 
                )
            }
        }) {
            Image( 
                painter = it, contentDescription = imgUrl, modifier = modifier, contentScale = contentScale 
            )
        })
    } else { 
        ImageRes(resName = imgUrl, imageCallback = ImageCallback(placeHolderView = { 
            placeHolderUrl?.let { 
                Image( 
                    painter = painterResource(placeHolderUrl), 
                    contentDescription = imgUrl, 
                    modifier = modifier, 
                    contentScale = contentScale 
                )
            }
        }, errorView = { 
            errorUrl?.let { 
                Image( 
                    painter = painterResource(errorUrl), 
                    contentDescription = imgUrl, 
                    modifier = modifier, 
                    contentScale = contentScale 
                )
            }
        }) {
            Image( 
                painter = it, contentDescription = imgUrl, modifier = modifier, contentScale = contentScale 
            )
        })
    }
}

致谢

项目中大部分技术栈都参考自NCMusicDesktop,感谢大佬