
回复
最近想把日常开发练习总结的APP上架到应用市场,由于之前APP内容都是最终的效果演示,看着有些单调,于是打算把对应的源码也加入到里面,可以直接阅读,和文章里的代码展示是一样的。
最终效果:
实现过程:
1.不知道鸿蒙有没有支持的三方库可以直接引用实现,我没有去查,最近刚好写Web的使用,正好可以结合HTML展示
2.对于一个移动端的开发程序员,写一个类似于Markdown的展示效果,也无从下手,于是找了AI帮忙,让他帮我写这个HTML,然后简单调试,直到效果满意
3.HTML中引用了Prism JS库,做过前端的同学可能了解,由于我想上架单机APP,所以就把这个js文件下载到了本地引用
4.Web与原生交互到这里肯定已经很熟悉了,只要将想要展示的代码通过js方法传入html就可以了
需要注意的点
测试过程中,有个坑需要注意,代码复制出来有很多特殊符号和 \ ,导致传入html后不能显示,所以需要对字符串进行格式化的处理。
展示代码的HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ArkTS代码展示</title>
<!-- 引入Prism样式(确保与HTML同目录) -->
<link rel="stylesheet" href="prism.css">
<!-- 引入Prism核心库和TypeScript语法支持(确保与HTML同目录) -->
<script src="prism.js"></script>
<style>
/* 重置默认样式,避免额外边距 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 页面背景:轻微灰色,与代码区区分 */
body {
background-color: #f5f5f5;
padding: 10px; /* 可选:给页面加少量内边距,避免代码贴边 */
}
/* 代码容器:仅保留代码区域,去掉顶部黑边(删除原头部相关样式) */
pre {
/* 代码区深色背景(Prism主题默认深色,如需浅色可改#fff) */
background-color: #1d1f21;
/* 代码内边距,确保文字不贴边 */
padding: 16px;
/* 移动端长代码横向滚动(核心适配) */
overflow-x: auto;
/* 代码字体大小:适配手机阅读 */
font-size: 14px;
/* 行高:提升可读性 */
line-height: 1.6;
/* 可选:轻微圆角,避免生硬(不需要可删除) */
border-radius: 6px;
/* 可选:轻微阴影,突出代码区(不需要可删除) */
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
/* 代码字体:等宽字体,确保代码格式对齐 */
code {
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
color: #ccc; /* 代码默认文字色,与深色背景适配 */
}
</style>
</head>
<body>
<!-- 仅保留代码展示核心区域:pre + code -->
<pre><code class="language-typescript" id="codeDisplay"></code></pre>
<script>
/**
* 接收并展示ArkTS代码的方法
* @param {string} code - 传入的ArkTS源代码
*/
function displayCode(code) {
const codeElement = document.getElementById('codeDisplay');
// 设置代码内容(空值时显示提示)
codeElement.textContent = code || '未传入代码,请调用 displayCode(代码字符串)';
// 触发Prism语法高亮
Prism.highlightElement(codeElement);
}
</script>
</body>
</html>
展示代码的组件
import { webview } from '@kit.ArkWeb'
import { util } from '@kit.ArkTS'
import { CaseRouterList } from '../model/CaseRouterList'
@Builder
export function CodeDisplayPage_Builder() {
CodeDisplayPage()
}
@Entry
@ComponentV2
struct CodeDisplayPage{
pageInfos: NavPathStack = new NavPathStack()
private webviewController: WebviewController = new webview.WebviewController()
@Local arkTSCode:string=''
@Local title:string=''
build() {
NavDestination(){
Scroll(){
Column(){
Web({
src: $rawfile('blank-arkts-display.html'),
controller: this.webviewController,
renderMode: RenderMode.SYNC_RENDER
})
.layoutMode(WebLayoutMode.FIT_CONTENT) // 设置为Web组件大小自适应页面内容
.overScrollMode(OverScrollMode.NEVER) // 设置过滚动模式为关闭状态
.onPageEnd((event) => {
let js = "displayCode('" + this.arkTSCode
// .replace(/'/g, '\\\'')
// .replace(/\n/g, '\\n')
// .replace(/\r/g, '\\r')
.replaceAll('\'', '\\\'')
.replaceAll('\n', '\\n')
.replaceAll('\r', '\\r')
+ "')";
this.webviewController.runJavaScript(js)
})
}
}
}
.onReady(async (context: NavDestinationContext) => {
this.pageInfos = context.pathStack
let parms:Array<string> = this.pageInfos.getParamByName("CodeDisplayPage") as Array<string>
let codePath:string=''
if (parms.length>0) {
let codeRouter : CaseRouterList= JSON.parse(parms[0])
this.title=codeRouter.pageName
codePath=codeRouter.pageRouter
}
let getJson = await getContext(this).resourceManager.getRawFileContent('code/'+codePath+'.ets');
let textDecoderOptions: util.TextDecoderOptions = { ignoreBOM : true };
let textDecoder = util.TextDecoder.create('utf-8',textDecoderOptions);
this.arkTSCode = textDecoder.decodeToString(getJson);
})
.title(this.title)
}
}
注意:
1.我这里是将要展示的代码放到了rawfile资源下,通过传入的文件名,直接读取文件里的全部代码,然后调用js展示出来。
2.读取的代码需要处理一下 ’ \n \r ,要全部替换,具体看代码