001 - 使用鸿蒙WebView创建简单浏览器 step 1 原创 精华
人工智能姬
发布于 2021-4-17 09:22
浏览
4收藏
-
打开官网,找到WebView的文档(模拟器不支持)
鸿蒙webview的开发指南(原始链接,方便大家识别并点击):https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-webview-0000001092715158
2. 创建一个Page Ability,把基本布局弄好
下面是代码
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical">
<DirectionalLayout
ohos:height="30vp"
ohos:width="match_parent"
ohos:orientation="horizontal">
<TextField
ohos:id="$+id:text_webView_Url"
ohos:height="match_content"
ohos:width="match_parent"
ohos:background_element="$graphic:background_ability_simple_web_view"
ohos:focus_border_enable="true"
ohos:hint="请输入网址"
ohos:max_text_lines="1"
ohos:multiple_lines="false"
ohos:scrollable="true"
ohos:text="www.harmonyos.com"
ohos:text_size="50"
ohos:weight="1"
/>
<Button
ohos:id="$+id:button_webview_surf"
ohos:height="match_content"
ohos:width="60vp"
ohos:background_element="$graphic:button_element"
ohos:text="跳转"
ohos:text_size="50"/>
</DirectionalLayout>
<ProgressBar
ohos:id="$+id:other_webView_progressBar"
ohos:height="10vp"
ohos:width="match_parent"
ohos:visibility="hide">
</ProgressBar>
<ohos.agp.components.webengine.WebView
ohos:id="$+id:webview_webview_webview"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:weight="1">
</ohos.agp.components.webengine.WebView>
<DirectionalLayout
ohos:height="30vp"
ohos:width="match_parent"
ohos:orientation="horizontal">
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:orientation="horizontal"
ohos:weight="1">
<Button
ohos:id="$+id:button_webview_back"
ohos:height="match_content"
ohos:width="match_parent"
ohos:background_element="$graphic:button_element"
ohos:layout_alignment="horizontal_center"
ohos:text="向后"
ohos:text_size="50"
>
</Button>
</DirectionalLayout>
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:orientation="horizontal"
ohos:weight="1">
<Button
ohos:id="$+id:button_webview_refresh"
ohos:height="match_content"
ohos:width="match_parent"
ohos:background_element="$graphic:button_element"
ohos:layout_alignment="horizontal_center"
ohos:text="刷新"
ohos:text_size="50">
</Button>
</DirectionalLayout>
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:orientation="horizontal"
ohos:weight="1">
<Button
ohos:id="$+id:button_webview_forward"
ohos:height="match_content"
ohos:width="match_parent"
ohos:background_element="$graphic:button_element"
ohos:layout_alignment="horizontal_center"
ohos:text="向前"
ohos:text_size="50">
</Button>
</DirectionalLayout>
</DirectionalLayout>
</DirectionalLayout>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
-
把基本的按钮事件弄好
序号 按钮 功能 1 跳转 把文本框中的网址打开 2 后退 在webview中点了新链接后,想回去看一看 3 刷新 以前的人在网络不好,美女图片出不来的时候用,现在一般是发了一篇帖子后,作者会没事点一下,看看有没有人点赞 4 前进 跟后退是关联用的,就是点了新链接,回去看了看后,还是觉得新链接更好看,就又要前进. 代码
Component.ClickedListener clickedListener = new Component.ClickedListener() { @Override public void onClick(Component component) { int componentId = component.getId(); switch (componentId) { case ResourceTable.Id_button_webview_surf: { urlAddress = textWebViewUrl.getText(); if (urlAddress.isEmpty()) { return; } if (!urlAddress.startsWith(FinalValue.URL_HTTPS)) { urlAddress = FinalValue.URL_HTTPS + urlAddress; } webView.load(urlAddress); } break; case ResourceTable.Id_button_webview_back: { if (webView.getNavigator().canGoBack()) { webView.getNavigator().goBack(); } } break; case ResourceTable.Id_button_webview_refresh: { webView.reload(); } break; case ResourceTable.Id_button_webview_forward: { if (webView.getNavigator().canGoForward()) { webView.getNavigator().goForward(); } } break; default: { System.out.println("没有选择任何的页面"); } break; } } };
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
-
把WebView照文档上面的要求弄好
没啥好说的,就是规定.我加在了调用load方法打开网址那行代码后面,我还弄了一个跟进度条关联的功能
//允许javascript交互 WebConfig webConfig = webView.getWebConfig(); webConfig.setDataAbilityPermit(true); webConfig.setJavaScriptPermit(true); webConfig.setLoadsImagesPermit(true); webConfig.setMediaAutoReplay(true); webConfig.setLocationPermit(true); webConfig.setSecurityMode(WebConfig.SECURITY_SELF_ADAPTIVE); webView.setWebAgent(new WebAgent() { @Override public void onLoadingPage(WebView webView, String url, PixelMap favicon) { super.onLoadingPage(webView, url, favicon); // 这儿我加了一个更新网址文本框中新页面url的功能 if (url != urlAddress) { textWebViewUrl.setText(url); } } @Override public void onPageLoaded(WebView webView, String url) { super.onPageLoaded(webView, url); // 页面加载结束后自定义处理 } @Override public void onLoadingContent(WebView webView, String url) { super.onLoadingContent(webView, url); // 加载资源时自定义处理 } @Override public void onError(WebView webView, ResourceRequest request, ResourceError error) { super.onError(webView, request, error); // 发生错误时自定义处理 } }); webView.setBrowserAgent(new BrowserAgent(SimpleWebViewAbilitySlice.this) { @Override public void onTitleUpdated(WebView webView, String title) { super.onTitleUpdated(webView, title); // 标题变更时自定义处理 } @Override public void onProgressUpdated(WebView webView, int newProgress) { super.onProgressUpdated(webView, newProgress); if (newProgress < FinalValue.PROGRESS_BAR_FINISHED) { otherWebViewProgressBar.setVisibility(Component.VISIBLE); otherWebViewProgressBar.setProgressValue(newProgress); } else if (newProgress == FinalValue.PROGRESS_BAR_FINISHED) { otherWebViewProgressBar.setVisibility(Component.HIDE); } // 加载进度变更时自定义处理 } });
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
-
完事?or完了还有事?
从上面拷代码的话,估计完事了.但是,我是用的回忆,但是代码却没有回退,所以我还是有必要在这儿把步骤中的问题说一说,方便不拷代码的同学也能跑出一个界面.主要体现如下:
-
权限配置,不多说
"reqPermissions": [ { "name": "ohos.permission.INTERNET" } ]
- 1.
- 2.
- 3.
- 4.
- 5.
-
xml中的WebView要带包名
<ohos.agp.components.webengine.WebView ohos:id="$+id:webview_webview_webview" ohos:height="match_parent" ohos:width="match_parent" ohos:weight="1"> </ohos.agp.components.webengine.WebView>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
不按上面包名写的话:
- 真机运行后没有WebView的界面.哪怕weight=1,也不行
- 点击跳转按钮后,PageAbility会闪退,回到首屏(调用它的页面)
-
-
完整代码
-
布局
序号为2的步骤中贴全了
-
按钮背景
<?xml version="1.0" encoding="UTF-8" ?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="20"/> <solid ohos:color="#70dbdb"/> </shape>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
-
java代码
package com.javaaier.family.huawei.slice; import com.javaaier.family.huawei.ResourceTable; import com.javaaier.family.huawei.common.FinalValue; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.components.*; import ohos.agp.components.webengine.*; import ohos.media.image.PixelMap; /** * @Author JavaAIer * @Description : webview控件例子1:用于简单的测试webview的用法 <br/> * 001 简单webview示例 * @Date: 2021/4/16 */ public class SimpleWebViewAbilitySlice extends AbilitySlice { String urlAddress; ProgressBar otherWebViewProgressBar; TextField textWebViewUrl; Button buttonWebViewSurf, buttonWebViewBack, buttonWebViewRefresh, buttonWebViewForward; WebView webView; Component.ClickedListener clickedListener = new Component.ClickedListener() { @Override public void onClick(Component component) { int componentId = component.getId(); switch (componentId) { case ResourceTable.Id_button_webview_surf: { urlAddress = textWebViewUrl.getText(); if (urlAddress.isEmpty()) { return; } if (!urlAddress.startsWith(FinalValue.URL_HTTPS)) { urlAddress = FinalValue.URL_HTTPS + urlAddress; } webView.load(urlAddress); //允许javascript交互 WebConfig webConfig = webView.getWebConfig(); webConfig.setDataAbilityPermit(true); webConfig.setJavaScriptPermit(true); webConfig.setLoadsImagesPermit(true); webConfig.setMediaAutoReplay(true); webConfig.setLocationPermit(true); webConfig.setSecurityMode(WebConfig.SECURITY_SELF_ADAPTIVE); webView.setWebAgent(new WebAgent() { @Override public void onLoadingPage(WebView webView, String url, PixelMap favicon) { super.onLoadingPage(webView, url, favicon); // 页面开始加载时自定义处理 if (url != urlAddress) { textWebViewUrl.setText(url); } } @Override public void onPageLoaded(WebView webView, String url) { super.onPageLoaded(webView, url); // 页面加载结束后自定义处理 } @Override public void onLoadingContent(WebView webView, String url) { super.onLoadingContent(webView, url); // 加载资源时自定义处理 } @Override public void onError(WebView webView, ResourceRequest request, ResourceError error) { super.onError(webView, request, error); // 发生错误时自定义处理 } }); webView.setBrowserAgent(new BrowserAgent(SimpleWebViewAbilitySlice.this) { @Override public void onTitleUpdated(WebView webView, String title) { super.onTitleUpdated(webView, title); // 标题变更时自定义处理 } @Override public void onProgressUpdated(WebView webView, int newProgress) { super.onProgressUpdated(webView, newProgress); if (newProgress < FinalValue.PROGRESS_BAR_FINISHED) { otherWebViewProgressBar.setVisibility(Component.VISIBLE); otherWebViewProgressBar.setProgressValue(newProgress); } else if (newProgress == FinalValue.PROGRESS_BAR_FINISHED) { otherWebViewProgressBar.setVisibility(Component.HIDE); } // 加载进度变更时自定义处理 } }); } break; case ResourceTable.Id_button_webview_back: { if (webView.getNavigator().canGoBack()) { webView.getNavigator().goBack(); } } break; case ResourceTable.Id_button_webview_refresh: { webView.reload(); } break; case ResourceTable.Id_button_webview_forward: { if (webView.getNavigator().canGoForward()) { webView.getNavigator().goForward(); } } break; default: { System.out.println("没有选择任何的页面"); } break; } } }; /** * @Author JavaAIer * @Description : * @Date: 2021/4/16 14:46 * * @param intent */ @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_simple_web_view); otherWebViewProgressBar = (ProgressBar) findComponentById(ResourceTable.Id_other_webView_progressBar); textWebViewUrl = (TextField) findComponentById(ResourceTable.Id_text_webView_Url); buttonWebViewSurf = (Button) findComponentById(ResourceTable.Id_button_webview_surf); buttonWebViewSurf.setClickedListener(clickedListener); buttonWebViewBack = (Button) findComponentById(ResourceTable.Id_button_webview_back); buttonWebViewBack.setClickedListener(clickedListener); buttonWebViewRefresh = (Button) findComponentById(ResourceTable.Id_button_webview_refresh); buttonWebViewRefresh.setClickedListener(clickedListener); buttonWebViewForward = (Button) findComponentById(ResourceTable.Id_button_webview_forward); buttonWebViewForward.setClickedListener(clickedListener); webView = (WebView) findComponentById(ResourceTable.Id_webview_webview_webview); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } } /* * 这一截卡哇伊大喵在config.json用了,我发现用不用没啥区别啊 * https://blog.csdn.net/qq_33259323/article/details/115596296 * "default": { "network": { "cleartextTraffic": true, "securityConfig": { "domainSettings": { "cleartextPermitted": true, "domains": [ { "subdomains": true, "name": "www.harmonyos.com" } ] } } } } * * */
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
-
- config.json
``` json
{
"app": {
"bundleName": "com.javaaier.family.huawei",
"vendor": "javaaier",
"version": {
"code": 1,
"name": "1.0"
},
"apiVersion": {
"compatible": 5,
"target": 5,
"releaseType": "Beta1"
}
},
"deviceConfig": {
},
"module": {
"package": "com.javaaier.family.huawei",
"name": ".MyApplication",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry"
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "unspecified",
"name": "com.javaaier.family.huawei.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:app_name",
"type": "page",
"launchType": "standard"
},
{
"orientation": "unspecified",
"name": "com.javaaier.family.huawei.SimpleWebViewAbility",
"icon": "$media:icon",
"description": "$string:simplewebviewability_description",
"label": "$string:app_name",
"type": "page",
"launchType": "standard"
}
],
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
赞
4
收藏 4
回复
分享
微博
QQ
微信
举报
举报
4
4
4
微信扫码分享
删除帖子
删除 取消
相关推荐
你好,请问FinalValue这个文件代码定义的什么
https://gitee.com/javaaier/HarmonyOSNotes/blob/master/codes/JavaAIer_HarmonyOS_App_Notes/entry/src/main/java/com/javaaier/family/huawei/common/FinalValue.java
时代变了,预览器也不支持了
是说模拟器吗?估计以后会支持吧.
而且以后的deveco还会支持分布式的模拟器联调,敬请期待.
目前刚起步,请多一点理解,比心.