1. Web组件简介
本系列的第18篇文章《鸿蒙网络编程系列18-Web组件加载网页的四种方式示例》中,使用ArkTS语言基于API 9环境演示了Web组件四种加载网页内容的方式,其中就包括使用WebviewController的loadData方法直接加载HTML脚本的方式。不过,目前的仓颉版本还不支持loadData方法,因此,本文将基于API 12环境演示Web组件加载网页的其他三种方式。
2. Web组件加载网页演示
本示例运行后的页面如图所示:
在这种默认的情况下,使用的是加载资源文件的方式,也就是预先把html文件作为资源文件嵌入到应用中,然后在初始化web组件时作为src属性传入:
Web(src: @rawfile("index.html"), controller: controller)
第二种方式是直接加载网址,输入网址后,单击网址后面的“加载”按钮即可进行网页加载,如图所示:
第三种方式是加载本地html文件,单击“选择”按钮,选择本地html文件,如图所示:
选择文件后,单击“完成”按钮回到主界面,再单击“加载按钮”即可加载本地html文件,如图所示:
3. HWeb组件加载网页示例编写
下面详细介绍创建该示例的步骤(确保DevEco Studio已安装仓颉插件)。
步骤1:创建[Cangjie]Empty Ability项目。
步骤2:在module.json5配置文件加上对权限的声明:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
这里添加了访问互联网的权限。
步骤3:在build-profile.json5配置文件加上仓颉编译架构:
"cangjieOptions": {
"path": "./src/main/cangjie/cjpm.toml",
"abiFilters": ["arm64-v8a", "x86_64"]
}
步骤4:在main_ability.cj文件里添加如下的引用:
import ohos.ability.*
然后定义变量globalContext:
var globalContext: Option<AbilityContext> = Option<AbilityContext>.None
在onCreate函数里添加如下的代码:
globalContext = this.context
步骤5:创建index.html文件,并添加如下的代码:
<!-- index.html -->
<!DOCTYPE html>
<html>
<body style="font-size: large;text-align: center;">
<div style="color:blue">Hello HarmonyOS Next</div>
<div>Load with resource file</div>
</body>
</html>
把index.html文件作为资源文件嵌入到应用中:
步骤6:在index.cj文件里添加如下的代码:
package ohos_app_cangjie_entry
import ohos.base.*
import ohos.component.*
import ohos.state_manage.*
import ohos.state_macro_manage.*
import std.collection.HashMap
import ohos.net.http.*
import ohos.file_picker.*
import ohos.ability.getStageContext
import ohos.ability.*
import ohos.file_fs.*
import ohos.webview.*
@Entry
@Component
class EntryView {
@State
var title: String = '仓颉版Web加载示例';
//要加载的网址
@State
var webUrl: String = "https://******"
//要加载的文件
@State
var loadFileUri: String = ""
let scroller: Scroller = Scroller()
let controller: WebviewController = WebviewController()
func build() {
Row {
Column {
Text(title).fontSize(14).fontWeight(FontWeight.Bold).width(100.percent).textAlign(TextAlign.Center).
padding(10)
Flex(FlexParams(justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center)) {
Text("网址:").fontSize(14)
TextInput(text: webUrl).onChange({
value => webUrl = value
}).width(100).fontSize(11).flexGrow(1)
Button("加载").onClick {
evt => this.controller.loadUrl(this.webUrl);
}.width(70).fontSize(14)
}.width(100.percent).padding(10)
Flex(FlexParams(justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center)) {
Text("文件:").fontSize(14)
TextInput(text: loadFileUri).onChange({
value => loadFileUri = value
}).width(100).fontSize(11).flexGrow(1)
Button("选择").onClick {
evt => selectLoadFile();
}.width(70).fontSize(14)
Button("加载").onClick {
evt => loadLocalFile()
}.width(70).fontSize(14)
}.width(100.percent).padding(10)
Scroll(scroller) {
Web(src: @rawfile("index.html"), controller: controller).domStorageAccess(true).fileAccess(true).
padding(10).width(100.percent).backgroundColor(0xeeeeee)
}.align(Alignment.Top).backgroundColor(0xeeeeee).height(300).flexGrow(1).scrollable(
ScrollDirection.Vertical).scrollBar(BarState.On).scrollBarWidth(20)
}.width(100.percent).height(100.percent)
}.height(100.percent)
}
//选择需要加载的文件
func selectLoadFile() {
let option = DocumentSelectOptions(maxSelectNumber: 1, selectMode: DocumentSelectMode.MIXED)
let documentPicker = DocumentViewPicker(globalContext.getOrThrow())
let documentSelectCallback = {
errorCode: Option<AsyncError>, data: Option<Array<String>> => match (errorCode) {
case Some(e) => ()
case _ => match (data) {
case Some(value) => loadFileUri = value[0]
case _ => ()
}
}
}
documentPicker.select(documentSelectCallback, option: option)
}
//加载本地文件
func loadLocalFile() {
let segments = this.loadFileUri.split('/')
//文件名称
let fileName = segments[segments.size - 1] + ".html"
//计划复制到的目标路径
let realUri = globalContext.getOrThrow().filesDir + "/" + fileName
//复制选择的文件到沙箱cache文件夹
let file = FileFs.open(this.loadFileUri);
FileFs.copyFile(file.fd, realUri)
FileFs.close(file);
this.controller.loadUrl("file://${realUri}");
}
}
步骤7:编译运行,可以使用模拟器或者真机,在当前版本下,最好使用真机。
步骤8:按照本节第2部分“Web组件加载网页演示”操作即可。
4. 代码分析
在加载本地文件时,需要复制本地文件到沙箱目录,再进行加载,加载时需要注意文件的路径格式,这里使用的是file前缀,对应代码如下所示:
func loadLocalFile() {
let segments = this.loadFileUri.split('/')
//文件名称
let fileName = segments[segments.size - 1] + ".html"
//计划复制到的目标路径
let realUri = globalContext.getOrThrow().filesDir + "/" + fileName
//复制选择的文件到沙箱cache文件夹
let file = FileFs.open(this.loadFileUri);
FileFs.copyFile(file.fd, realUri)
FileFs.close(file);
this.controller.loadUrl("file://${realUri}");
}
(本文作者原创,除非明确授权禁止转载)
本文源码地址:
https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/web/WebDemo4Cj