RtText:我为Kotlin Multiplatform Compose 写了一个富文本显示器

RtText:Kotlin Multiplatform Compose HTML & Markdown 显示组件

由于KMM没有自带的WebView,虽然第三方社区有一个WebView库在维护,但在我使用的过程中发现,由于Kotlin Multiplatform底层原因,导致WebView在IOS设备上,无法与compose组件嵌套滑动。

而我仅仅只是需要显示Html罢了,所以诞生了RtText,一个纯Compose实现的富文本显示器

RtText是Kotlin Multiplatform 库,支持多平台IOS、Android、Destop。

示例

计划

  • 完善Html标签支持
  • 支持Markdown显示

RtText目前支持的HTML标签有:h1,h2,h3,h4,h5,h6,a,b,strong,ol,ul,p,img,table

  • CSS: RtText支持设置简单的CSS属性
  • 扩展标签:RtText支持自定义标签

添加到项目

RtText发布在Maven Central仓库

添加依赖项 到commonMain. 最新版本

kotlin 复制代码
implementation("cn.changjiahong:RtText:<version>")

快速开始

协议链接

kotlin 复制代码
    val license = "勾选即代表你同意本应用<a href=\"https://ex.license.com\"><b>使用协议</b></a>。"

    RtHtml(
        license,
        modifier = Modifier.fillMaxSize(),
        linkAction = { link ->
            openLink(link)
        }
    )

跳转注册

kotlin 复制代码
  val regsiter =
        "你还没有账号?点击跳转<a style=\" color:#ffdd0000\" href=\"register\"><b>注册</b></a>。"
        
   RtHtml(
        regsiter,
        modifier = Modifier.fillMaxSize(),
        linkAction = { tag ->
            when(tag){
                "register" -> goToRegister()
            }
        }
    )

CSS风格

RtText默认提供了一组github风格CSS,你也可以自定义CSS。

kotlin 复制代码
val customCss = """
        .post-md
        {
            width: 100%;
            font-size: 16.8px;
            letter-spacing: 0;
        }
    
        .post-md h1,
        .post-md h2,
        .post-md h3,
        .post-md h4,
        .post-md h5,
        .post-md h6
        {
            color: #000;
            margin: 12px 0;
        }
        .post-md h1
        {
            font-size: 2.5rem;
            line-height: 1.2;
            padding: 24px 0;
        }
        .post-md h2
        {
            font-size: 2rem;
            line-height: 1.2;
            padding: 20px 0;
        }
        .post-md h3
        {
            font-size: 1.75rem;
            line-height: 1.2;
            padding: 18px 0;
        }
        .post-md h4
        {
            font-size: 1.5rem;
            line-height: 1.2;
            padding: 16px 0;
        }
        .post-md h5
        {
            font-size: 1.25rem;
            line-height: 1.2;
            padding: 14px 0;
        }
        .post-md h6
        {
            font-size: 1.125rem;
            line-height: 1.2;
            padding: 12px 0;
        }
        .post-md a
        {
            color: #666;
            box-shadow: 0 2px 0 #ccc;
            /* transition: color ease-in-out .65s, box-shadow ease-in-out .65s; */
        }
    """.trimIndent()

    RtHtml(
        html,
        css = customCss,
        modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
        linkAction = {
            println(it)
        }
    )

自定义标签

简单标签处理器

RtText默认支持的标签处理器defaultNodeHandlers,若要扩展新的处理器,则只需要实现NodeHandler并注册即可。

kotlin 复制代码
// 自定义blod标签,支持字体加粗显示
val blod = NodeHandler("blod") { node: Node ->
    val (spanStyle, paragraphStyle) = node.parseStyle()
    withStyle(style = SpanStyle(fontWeight = FontWeight.Bold).merge(spanStyle)) {
        appendChild(node)
    }
}

// nodeHandlers里注册blod
RtHtml(
        html,
        nodeHandlers = mutableListOf(blod).apply { addAll(defaultNodeHandlers) },
        modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
        linkAction = {
            println(it)
        }
    )

特殊标签处理器

RtText中若要绘制特殊显示,如img,table等标签,则可实现InlineNodeProcessor处理器。

kotlin 复制代码
// 代码块标签处理器
val code =
    InlineNodeProcessor("code") {
        val param: Param = Json.decodeFromString(it)
        val codeNode = Ksoup.parse(param.contentText).body().firstChild()!!
        Box(modifier = Modifier.fillMaxWidth().wrapContentHeight().background(Color.Yellow)) {
            Text(codeNode.outHtml())
        }
    }

如果需要改变内嵌控件的高度,则可调用handlerContext.updateInlineContent()更新

kotlin 复制代码
val density = LocalDensity.current.density
val fontScale = LocalDensity.current.fontScale
val handlerContext = LocalHandlerContext.current

Box(modifier = Modifier
    .onSizeChanged { size ->
        handlerContext.updateInlineContent(
            param, (size.width / density * fontScale).sp,
            (size.height / density * fontScale).sp,
        )
}){
    Text("")
}

依赖

RtText依赖以下lib,如果你使用了RtText,则不需要再重复添加该库

觉得此存储库有用?

通过加入此存储库的 stargazers 来支持它。⭐ 也可以 Follow Me 一起创作吧!🤩

相关推荐
難釋懷1 小时前
Android开发-Application
android
seven27293 小时前
Android 适配之——targetSdkVersion 30升级到31-34需要注意些什么?
android·版本设置31-34·targetsdk
androidwork5 小时前
Kotlin Android单元测试MockK指南
android·kotlin
麻辣璐璐5 小时前
Kotlin并发请求的一些知识记录
android·kotlin
东风西巷5 小时前
MobiPDF:安卓设备上的专业PDF阅读与编辑工具
android·智能手机·pdf·软件需求
難釋懷7 小时前
Android开发-在应用之间共享数据
android·jvm·oracle
難釋懷9 小时前
Android开发-数据库SQLite
android·数据库·sqlite
Jouzzy9 小时前
【iOS安全】Dopamine越狱 iPhone X iOS 16.6 (20G75) | 解决Jailbreak failed with error
安全·ios·iphone
瓜子三百克9 小时前
采用sherpa-onnx 实现 ios语音唤起的调研
macos·ios·cocoa
androidwork9 小时前
Arrow库:函数式编程在Kotlin Android中的深度实践
android·java·kotlin