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 一起创作吧!🤩

相关推荐
simplepeng1 小时前
Room 3.0 KMP Alpha-01
android·kotlin·android jetpack
Lei活在当下1 小时前
Windows 下 Codex 高效工作流最佳实践
android·openai·ai编程
fatiaozhang95271 小时前
基于slimBOXtv 9.19.0 v4(通刷晶晨S905L3A/L3AB芯片)ATV-安卓9-完美版线刷固件包
android·电视盒子·刷机固件·机顶盒刷机·晶晨s905l3ab·晶晨s905l3a
私房菜2 小时前
Selinux 及在Android 的使用详解
android·selinux·sepolicy
一只特立独行的Yang3 小时前
Android中的系统级共享库
android
两个人的幸福online3 小时前
php开发者 需要 协程吗
android·开发语言·php
修炼者5 小时前
WindowManager(WMS)构建全局悬浮窗
android
xiaoshiquan12065 小时前
Android Studio里,SDK Manager显示不全问题
android·ide·android studio
Lstone73646 小时前
Bitmap深入分析(一)
android
一起搞IT吧7 小时前
Android功耗系列专题理论之十四:Sensor功耗问题分析方法
android·c++·智能手机·性能优化