HarmonyOS 使用富文本组件和web组件加载html页面
引言
在鸿蒙开发中有些场景需要使用html的功能才能完成,比如关键字高亮,特殊格式的文本等,因此RichText组件和web组件的作用就显的格外重要。
RichText富文本
带有html标签包裹住的文本叫做富文本例如:<h1>hello</h1>、<p>hello</p>
直接写会出现文字显示非常小,看不清楚的问题列如:RichText(<h1>这是一个富文本<h1>)
可以使用一段html结构+div 设置字体大小来解决
RichText(`
<html>
<body>
<div style="font-size:45px"><h1>这是一个富文本</h1></div>
<body>
</html>
`)
使用富文本来显示html格式的内容会很方便但是也存在着性能方面的问题。如RichText组件比较消耗内存资源,在List组件中循环重复使用RichText时,会出现卡顿、滑动响应慢等现象,这时建议使用RichEditor组件。
web组件
web组件可以加载在线网页,沙箱中的页面,项目中entry/src/main/resources/rawfile下的静态html网页,可以说是功能相当强大。
但是需要注意,访问在线网页时需添加网络权限:ohos.permission.INTERNET,web组件不跟随转场动画。在ArkTS中web组件不再限于一个页面仅支持一个web组件,可以在同一个页面中使用多个web组件但是需要注意,同一页面的多个Web组件,必须绑定不同的WebviewController。
加载在线网页
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Web({ src: 'www.baidu.com', controller: this.controller })
.width('100%')
}
.width('100%')
}
}
请求来的在线网页是这个样子的
加载在线网页时需要开启模拟器的网络权限
加载本地网页
首选要在本地的目录下有html页面,html页面内容如下
<!doctype html>
<html>
<html>
<body>
<div style="font-size: 45px;">
我是web组件加载的本地网页
</div>
</body>
</html>
ArkTS代码如下
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
// 通过$rawfile加载本地资源文件。
Web({ src: $rawfile("My.html"), controller: this.controller })
}
}
}
如果成功加载就可以在模拟器上看到如下结果
加载沙箱路径下的本地资源文件
import fs from '@ohos.file.fs';
@State url:string = ''
str = `<!DOCTYPE html>
<html>
<body>
<div style="font-size: 45px;">
<p>Hello World</p>
</div>
</body>
</html>`
writehtml() {
//往沙箱中写入
try {
const file = fs.openSync(getContext().cacheDir + '/My2.html', fs.OpenMode.WRITE_ONLY | fs.OpenMode.CREATE)//有了就只写入,如果原本有内容会被清空,没有就新建文件再写入
fs.writeSync(file.fd,this.str)
AlertDialog.show({
message: '写入成功',
})
this.url = getContext().cacheDir + '/' + 'My2.html' //获取写入沙箱中文件的地址
AlertDialog.show({
//看一下写入的地址是否正确
message:this.url,
})
//删除
// fs.unlinkSync(getContext().cacheDir+ '/'+'My2.html')//fs删除指定目录下文件的同步方法
} catch (err) {
AlertDialog.show({
message: JSON.stringify(err, null, 2),
})
}
}
使用fs包中的writeSync同步方法,把str中的内容写入到沙箱中,写入成功的话可以在下图位置找到写入的文件
base下面的路径一定要根据项目中的bundleName来确定,否则找不到写在沙箱中的文件。
如果需要删除可以单独运行
fs.unlinkSync(getContext().cacheDir+ '/'+'My2.html')来删除,因为沙箱中的文件更改后没有权限保存,所以需要通过代码删除,也可以直接在模拟器中把应用卸载,清空沙箱中的缓存就会全部被清空。
通过如下代码来加载沙箱中的html文件
webviewController = new webview.WebviewController()
aboutToAppear(): void {
this.writehtml()
}
build() {
Column() {
if(this.url){
Web({
src: this.url,
controller: this.webviewController
})
.height(300)
.width('100%')
.domStorageAccess(true)
.fileAccess(true)
}else{
Text(`url为空`)
}
}
.width('100%')
.height('100%')
}
}
如果成功可以在模拟器中看到加载的html页面
注: web组件的这两个属性必须开启才可以从缓存读取到内容,否则可能出现光占了位置却没有内容的情况。 .domStorageAccess(true).fileAccess(true)
总代码:
import fs from '@ohos.file.fs';
import { webview } from '@kit.ArkWeb';
export class GlobalContext {
private constructor() {
}
private static instance: GlobalContext;
private _objects = new Map<string, Object>();
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext();
}
return GlobalContext.instance;
}
getObject(value: string): Object | undefined {
return this._objects.get(value);
}
setObject(key: string, objectClass: Object): void {
this._objects.set(key, objectClass);
}
}
@Entry
@Component
struct Index {
@State url:string = ''
str = `<!DOCTYPE html>
<html>
<body>
<div style="font-size: 45px;">
<p>Hello World</p>
</div>
</body>
</html>`
writehtml() {
//往沙箱中写入
try {
const file = fs.openSync(getContext().cacheDir + '/My2.html', fs.OpenMode.WRITE_ONLY | fs.OpenMode.CREATE)
fs.writeSync(file.fd,this.str)
AlertDialog.show({
message: '写入成功',
})
// 'file://' + file.path
this.url = getContext().cacheDir + '/' + 'My2.html'
AlertDialog.show({
message:this.url,
})
//删除
// fs.unlinkSync(getContext().cacheDir+ '/'+'My2.html')
} catch (err) {
AlertDialog.show({
message: JSON.stringify(err, null, 2),
})
}
}
webviewController = new webview.WebviewController()
aboutToAppear(): void {
this.writehtml()
}
build() {
Column() {
if(this.url){
Web({
src: this.url,
controller: this.webviewController
})
.height(300)
.width('100%')
.domStorageAccess(true)
.fileAccess(true)
}else{
Text(`url为空`)
}
}
.width('100%')
.height('100%')
}
}