简体   繁体   English

Kotlin 多平台 Compose + 桌面 + Web + 移动

[英]Kotlin Multiplatform Compose + Desktop + Web + Mobile

Is it possible at the moment to have a kotlin multiplatform project using compose for sharing the ui code for desktop, web, and mobile at the same time?目前是否有可能有一个使用 compose 的 kotlin 多平台项目来同时共享桌面、Web 和移动设备的 ui 代码? All the examples i found only cover multiplatform with JS Front + Jvm Backend, or JVM Android + Desktop + Common Module, and I'm having trouble setting a project with all those at the same time.我发现的所有示例都仅涵盖 JS Front + Jvm Backend 或 JVM Android + Desktop + Common Module 的多平台,而且我无法同时使用所有这些设置项目。

I tried doing:我试着做:

plugins {
    kotlin("multiplatform")
    id("org.jetbrains.compose") version "1.0.1-rc2"
    id("com.android.library")
}
kotlin {
    android()
    jvm("desktop") {
       ...
    }
    js{
       ...
    }
    sourceSets {
        val commonMain by getting {
            dependencies {
               ...
            }
        }
        val commonTest by getting {
            dependencies {
               ...
            }
        }
        val androidMain by getting {
            dependencies {
                ...
            }
        }
        val androidTest by getting {
            dependencies {
                ...
            }
        }
        val desktopMain by getting {
            dependencies {
                ...
            }
        }
        val desktopTest by getting
        val jsMain by getting{
            dependencies{
                ...
            }
        }
        val jsTest by getting {
            dependencies {
                ...
            }
        }
    }
}

But it produces the error:但它会产生错误:

:common:jsMain: Could not resolve org.jetbrains.compose.runtime:runtime:1.0.1-rc2.
Required by:
    project :common

If i comment the JS related sections it works, or if i comment all the non-js related stuff it also works如果我评论与 JS 相关的部分,它可以工作,或者如果我评论所有非 js 相关的东西,它也可以工作

Commenting everything compose-related also works评论所有与撰写相关的内容也有效

The problem is only when combining everything问题仅在于结合所有内容时

The short answer is: No , this is not possible at this time.简短的回答是:,目前这是不可能的。

The JB team is working on such support, which can be tested in these examples , but for now it is experimental and there is no guarantee that it will be released any time soon. JB 团队正在开发此类支持,可以在这些示例中进行测试,但目前它是实验性的,不能保证它会很快发布。 Compose JB version is now synced with Android Compose, so I expect that 1.2.0 will be released around the same time by both of them, even if Web support is not yet complete. Compose JB 版本现在与 Android Compose 同步,所以我预计它们将在同一时间发布1.2.0 ,即使 Web 支持尚未完成。


I have not been able to reproduce your error, but I assume that you have not removed compose.foundation and compose.material from the common dependencies.我无法重现您的错误,但我假设您尚未从公共依赖项中删除compose.foundationcompose.material

At the moment, only compose.runtime is available for the common module, and this makes it almost impossible to do any layout at this point: even Button and Text are not available.目前,只有compose.runtime可用于 common 模块,这使得此时几乎无法进行任何布局:甚至ButtonText都不可用。

As you can see in the JS application example, Text is not imported from androidx.compose.material.Text , but from org.jetbrains.compose.web.dom.Text , which is a completely different element, so it cannot be used in a common module.在 JS 应用示例中可以看到, Text不是从androidx.compose.material.Text导入的,而是从org.jetbrains.compose.web.dom.Text的,这是一个完全不同的元素,所以不能在一个通用模块。

At this point, I would say that Compose JS is another framework that allows you to write UI in Compose style.在这一点上,我想说 Compose JS 是另一个允许您以 Compose 风格编写 UI 的框架。

Jetbrains updated the github repo with some samples: Jetbrains 用一些示例更新了 github 存储库:

https://github.com/JetBrains/compose-jb/tree/master/experimental/examples https://github.com/JetBrains/compose-jb/tree/master/experimental/examples

It is possible now with version "1.2.0-alpha01-dev675" but not all components work and it is still in a somewhat early alpha stage.现在可以使用版本“1.2.0-alpha01-dev675”,但并非所有组件都可以正常工作,它仍处于早期的 alpha 阶段。

** **

This answer is not an exact answer to this question.这个答案不是这个问题的确切答案。 The correct answer for this is the answer by @PhilipDukhov.正确答案是@PhilipDukhov 的答案。 However, this might help others who land on this page for finding a solution to the other problem I am just leaving it here.但是,这可能会帮助登陆此页面的其他人找到解决其他问题的方法,我只是将其留在这里。 For more info read comments between me and @PhilipDukhov for this answer.有关更多信息,请阅读我和@PhilipDukhov 之间的评论以获得此答案。

** **

Yes, it is possible to have all three modules in a single project.是的,可以在一个项目中包含所有三个模块。 TLDR TLDR

I did some workarounds and managed to get all things in a single project ie我做了一些解决方法并设法在一个项目中得到所有东西,即

  1. Compose for Desktop为桌面撰写
  2. Compose for Android为 Android 编写
  3. Compose for Web为网络撰写

Suggestion Before You Go Further进一步前的建议

Although below code snippets works and by going through you will be able to achieve what you want actually.虽然下面的代码片段有效并且通过你将能够实现你真正想要的。 I personally recommend you to just go to the Github repository here .我个人建议你去这里的 Github 存储库。 I think it will save time if you are creating a new project.如果您正在创建一个新项目,我认为这将节省时间。 However if you are adding web module to current KMM project continue reading.但是,如果您将 Web 模块添加到当前的 KMM 项目,请继续阅读。

The problem can be fixed by keeping the correct dependencies可以通过保持正确的依赖关系来解决问题

So the project structure should be something like this所以项目结构应该是这样的

在此处输入图像描述

Note: If you are creating a new KMM project you will have only common, desktop, and android modules.(As you already know)注意:如果您正在创建一个新的 KMM 项目,您将只有 common、desktop 和 android 模块。(如您所知)

Step 1: You need to add the a folder to root (where the android, common,desktop folder is located) call it as web (should not matter)第1步:您需要将a文件夹添加到root(android,common,desktop文件夹所在的位置)将其称为web (应该没关系)

Step 2: Add several folders to this newly created directory web your web directory should look something like this第 2 步:将几个文件夹添加到这个新创建的目录 web 你的 web 目录应该看起来像这样

在此处输入图像描述

Note : Dont add build (its autogenerated) add only注意:不要添加构建(它的自动生成)只添加

src/jsMain
   -kotlin
   -resources
src/jsTest 
    -kotlin
   -resources

and create a file called build.gradle.kts并创建一个名为build.gradle.kts的文件

Step 3: Change the content of this newly added Gradle file to something like this第 3 步:将这个新添加的 Gradle 文件的内容更改为类似这样的内容

import org.jetbrains.compose.compose
import org.jetbrains.compose.desktop.application.dsl.TargetFormat

plugins {
    kotlin("multiplatform")
    id("org.jetbrains.compose") version "1.0.0"
}

group = "com.example"
version = "1.0"

kotlin {
    js(IR) {
        browser {
            testTask {
                testLogging.showStandardStreams = true
                useKarma {
                    useChromeHeadless()
                    useFirefox()
                }
            }
        }
        binaries.executable()
    }
    sourceSets {
        val jsMain by getting {
            dependencies {
                implementation(compose.web.core)
                implementation(compose.runtime)
            }
        }
        val jsTest by getting {
            dependencies {
                implementation(kotlin("test-js"))
            }
        }
    }
}

Step 4: And Add Main.kt to jsMain/kotlin with following content第 4 步:并将 Main.kt 添加到jsMain/kotlin中,内容如下

 renderComposable(rootElementId = "root") {
    Div(
        attrs = {
            // specify attributes here
            style {
                // specify inline style here
            }
        }
    ) {
        Text("A text in <div>")
    }
}

Step 4 : Add index.html to jsMain/resources with content第 4 步:将 index.html 添加到带有内容的 jsMain/resources

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>MultiplatformTest Sample</title>
</head>
<body>
<div id="root"></div>
<script src="web.js"></script>
</body>
</html>

Note: web.js file mentioned in the above snippet is sensitive and the project generated you need to make sure it is web.js only or else the folder_name.js which you created in step 1注意:上述代码段中提到的 web.js 文件是敏感文件,您需要确保生成的项目仅是 web.js,否则是您在步骤 1 中创建的 folder_name.js

Step 5: Finally add web module to settings.gradle.kts file第 5 步:最后将 web 模块添加到 settings.gradle.kts 文件

pluginManagement {
    repositories {
        google()
        jcenter()
        gradlePluginPortal()
        mavenCentral()
        maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
    }
    
}
rootProject.name = "MultiplatformTest"


include(":android")
include(":desktop")
include(":common")
include(":web")  // Note web module is included here 

I have created a repo check this repo and you can use it as a template for your projects我已经创建了一个 repo 检查这个 repo,你可以将它用作你的项目的模板

Link to the repo: https://github.com/PSPanishetti/ComposeMultiplatform链接到 repo: https ://github.com/PSPanishetti/ComposeMultiplatform

If you get any doubts feel free to ask them.如果您有任何疑问,请随时问他们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM