基于WebView的浏览器[Hello WebView][API V6]
基于WebView的浏览器[Hello WebView][API V6]
目录
1. 浏览器名称
- 将此项目所开发的浏览器命名为:Hello WebView,version 1.0.0。
- 项目已经放置在gitee中:HarmonyOS应用开发项目集合
2. 功能描述
- 经典三段式页面结构,上方是一个输入框一个搜索按钮,中间是工作区域(动态加载提示文本或WebView),下方是用户操作栏,包括一个返回按钮、一个前进按钮、一个多功能按钮。
- 多功能按钮:单击——刷新页面(调用reload())、双击——重置(解除WebView显示操作提示文本)、长按——装载WebView组件。点击搜索按键在用户执行“长按”之后才会生效。
3. 源代码
3.1 XML
3.1.1 主页面UI
ability_main.xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:WedViewRootdl"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="center">
<DirectionalLayout
ohos:id="$+id:WedViewRootdl_ddl1"
ohos:height="0"
ohos:weight="0.5"
ohos:width="match_parent"
ohos:left_padding="4vp"
ohos:right_padding="4vp"
ohos:top_padding="3vp"
ohos:bottom_padding="3vp"
ohos:orientation="horizontal"
ohos:alignment="vertical_center">
<TextField
ohos:id="$+id:WedViewRootdl_ddl1_toptfd"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="8"
ohos:hint="请输入链接"
ohos:text_alignment="center"
ohos:text_size="23vp"
ohos:hint_color="#FFF8E2D3"
ohos:background_element="$graphic:background_ability_ddl1_toptfd">
</TextField>
<Button
ohos:id="$+id:WedViewRootdl_ddl1_searchbutton"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="2"
ohos:text="Go"
ohos:text_alignment="center"
ohos:text_size="23vp"
ohos:text_color="#FFFFFFFF"
ohos:background_element="$graphic:background_ability_ddl1_searchbutton">
</Button>
</DirectionalLayout>
<DirectionalLayout
ohos:id="$+id:WedViewRootdl_ddl2"
ohos:height="0"
ohos:weight="9"
ohos:width="match_parent"
ohos:left_margin="4vp"
ohos:right_margin="4vp"
ohos:top_margin="3vp"
ohos:bottom_margin="3vp"
ohos:orientation="vertical"
ohos:alignment="center"
ohos:background_element="$graphic:background_ability_ddl2">
</DirectionalLayout>
<DirectionalLayout
ohos:id="$+id:WedViewRootdl_ddl3"
ohos:height="0"
ohos:weight="0.5"
ohos:width="match_parent"
ohos:left_margin="4vp"
ohos:right_margin="4vp"
ohos:left_padding="7vp"
ohos:right_padding="7vp"
ohos:top_padding="4vp"
ohos:bottom_padding="4vp"
ohos:orientation="horizontal"
ohos:alignment="vertical_center"
ohos:background_element="$graphic:background_ability_ddl3">
<Button
ohos:id="$+id:WedViewRootdl_ddl3_backbutton"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:text="$string:webview_backbutton"
ohos:text_alignment="center"
ohos:text_size="23vp"
ohos:text_color="#FF487EE7">
</Button>
<Button
ohos:id="$+id:WedViewRootdl_ddl3_rebutton"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:text="刷新-单/重置-双"
ohos:text_alignment="center"
ohos:text_size="13vp"
ohos:text_color="#FF03ACAA"
ohos:background_element="#FFF6F3F3">
</Button>
<Button
ohos:id="$+id:WedViewRootdl_ddl3_gobutton"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:text="$string:webview_gobutton"
ohos:text_alignment="center"
ohos:text_size="23vp"
ohos:text_color="#FF487EE7">
</Button>
</DirectionalLayout>
</DirectionalLayout>
3.1.2 动态装载页面(提示文本和WebView)
ability_sublayoutnotice.xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:subNoticerootdl"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="center"
ohos:background_element="$graphic:background_ability_subwebview">
<Text
ohos:id="$+id:subNoticerootdl_the_NoticeText"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:text="【操作提示】"
ohos:text_size="25vp"
ohos:text_color="red"
ohos:text_alignment="center"
ohos:multiple_lines="true">
</Text>
</DirectionalLayout>
ability_sublayoutwebview.xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:subWedViewRootdl"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="center"
ohos:background_element="$graphic:background_ability_subwebview">
<ohos.agp.components.webengine.WebView
ohos:id="$+id:subWedViewRootdl_the_webview"
ohos:height="match_parent"
ohos:width="match_parent">
</ohos.agp.components.webengine.WebView>
</DirectionalLayout>
3.1.3 背景XML UI
background_ability_ddl1_toptfd.xml
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="30vp"/>
<stroke
ohos:width="3vp"
ohos:color="#FF04A6B1"/>
<solid
ohos:color="#FFFFFFFF"/>
</shape>
background_ability_ddl1_searchbutton.xml
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="30vp"/>
<stroke
ohos:width="3vp"
ohos:color="#FFE39104"/>
<solid
ohos:color="#FF0EC6B4"/>
</shape>
background_ability_ddl2.xml
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="10vp"/>
<stroke
ohos:width="3vp"
ohos:color="#FF057DA9"/>
<solid
ohos:color="#FFDDF6EF"/>
</shape>
background_ability_ddl3.xml
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="10vp"/>
<stroke
ohos:width="3vp"
ohos:color="#FFBAF6EB"/>
<solid
ohos:color="#FFBAF6EB"/>
</shape>
background_ability_subwebview.xml
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="10vp"/>
</shape>
3.2 Java代码
3.2.1 MainAbilitySlice.java
package com.tdtxdcxm.hellowebview.slice;
import com.tdtxdcxm.hellowebview.ResourceTable;
import com.tdtxdcxm.hellowebview.webconfig.StartWebView;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.components.webengine.WebView;
public class MainAbilitySlice extends AbilitySlice {
private TextField WedViewRootdl_ddl1_toptfd;
private Button WedViewRootdl_ddl1_searchbutton;
private DirectionalLayout WedViewRootdl_ddl2;
private WebView subWedViewRootdl_the_webview;
private Text subNoticerootdl_the_NoticeText;
private Button WedViewRootdl_ddl3_backbutton,WedViewRootdl_ddl3_rebutton,WedViewRootdl_ddl3_gobutton;
public void init_noticelayout(DirectionalLayout ddl2){
ddl2.removeAllComponents();
DirectionalLayout subNoticerootdl = (DirectionalLayout) LayoutScatter.getInstance(MainAbilitySlice.this).parse(ResourceTable.Layout_ability_sublayoutnotice,null,false);
subNoticerootdl_the_NoticeText = (Text) subNoticerootdl.findComponentById(ResourceTable.Id_subNoticerootdl_the_NoticeText);
subNoticerootdl_the_NoticeText.setText("操作提示"+"\n"+"单击---刷新 双击---重置"+"\n"+"长按---加载WebView");
ddl2.addComponent(subNoticerootdl);
}
public void init_MainAbilitySliceComponents(){
WedViewRootdl_ddl1_toptfd = (TextField) findComponentById(ResourceTable.Id_WedViewRootdl_ddl1_toptfd);
WedViewRootdl_ddl1_searchbutton = (Button) findComponentById(ResourceTable.Id_WedViewRootdl_ddl1_searchbutton);
WedViewRootdl_ddl2 = (DirectionalLayout) findComponentById(ResourceTable.Id_WedViewRootdl_ddl2);
WedViewRootdl_ddl3_backbutton = (Button) findComponentById(ResourceTable.Id_WedViewRootdl_ddl3_backbutton);
WedViewRootdl_ddl3_rebutton = (Button) findComponentById(ResourceTable.Id_WedViewRootdl_ddl3_rebutton);
WedViewRootdl_ddl3_gobutton = (Button) findComponentById(ResourceTable.Id_WedViewRootdl_ddl3_gobutton);
init_noticelayout(WedViewRootdl_ddl2);
WedViewRootdl_ddl1_searchbutton.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
WedViewRootdl_ddl1_toptfd.clearFocus();
if(StartWebView.setwebviewstatus == true) {
subWedViewRootdl_the_webview.load(WedViewRootdl_ddl1_toptfd.getText());
}
}
});
WedViewRootdl_ddl3_backbutton.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
WedViewRootdl_ddl1_toptfd.clearFocus();
if(StartWebView.setwebviewstatus == true && subWedViewRootdl_the_webview.getNavigator().canGoBack()){
subWedViewRootdl_the_webview.getNavigator().goBack();
}
}
});
/****************************************给底部中间按钮设置监听器************************************/
WedViewRootdl_ddl3_rebutton.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
WedViewRootdl_ddl1_toptfd.clearFocus();
if(StartWebView.setwebviewstatus == true){
subWedViewRootdl_the_webview.reload();
}
}
});
WedViewRootdl_ddl3_rebutton.setDoubleClickedListener(new Component.DoubleClickedListener() {
@Override
public void onDoubleClick(Component component) {
WedViewRootdl_ddl2.removeAllComponents();
StartWebView.setwebviewstatus = false;
WedViewRootdl_ddl1_toptfd.clearFocus();
WedViewRootdl_ddl1_toptfd.setText("");
init_noticelayout(WedViewRootdl_ddl2);
}
});
WedViewRootdl_ddl3_rebutton.setLongClickedListener(new Component.LongClickedListener() {
@Override
public void onLongClicked(Component component) {
if(WedViewRootdl_ddl2.findComponentById(ResourceTable.Id_subWedViewRootdl_the_webview) == null) {
WedViewRootdl_ddl2.removeAllComponents();
DirectionalLayout subWedViewRootdl = (DirectionalLayout) LayoutScatter.getInstance(MainAbilitySlice.this).parse(ResourceTable.Layout_ability_sublayoutwebview, null, false);
subWedViewRootdl_the_webview = (WebView) subWedViewRootdl.findComponentById(ResourceTable.Id_subWedViewRootdl_the_webview);
WedViewRootdl_ddl2.addComponent(subWedViewRootdl);
StartWebView.startWebview(subWedViewRootdl_the_webview, "https://cn.bing.com/");
subWedViewRootdl_the_webview.load("https://cn.bing.com/");
}
}
});
/****************************************给底部中间按钮设置监听器************************************/
WedViewRootdl_ddl3_gobutton.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
WedViewRootdl_ddl1_toptfd.clearFocus();
if(StartWebView.setwebviewstatus == true && subWedViewRootdl_the_webview.getNavigator().canGoForward()){
subWedViewRootdl_the_webview.getNavigator().goForward();
}
}
});
}
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
init_MainAbilitySliceComponents();
}
@Override
public void onInactive() {
super.onInactive();
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
public void onBackground() {
super.onBackground();
}
@Override
public void onStop() {
super.onStop();
}
}
3.2.2 SetWebAgent.java
package com.tdtxdcxm.hellowebview.webconfig;
import ohos.agp.components.webengine.*;
import ohos.media.image.PixelMap;
import ohos.utils.net.Uri;
public class SetWebAgent extends WebAgent {
public String URL;
@Override
public void onLoadingPage(WebView webview, String url, PixelMap icon) {
super.onLoadingPage(webview, url, icon);
System.out.println("网页未知阶段!");
}
@Override
public void onPageLoaded(WebView webview, String url) {
System.out.println("网页已关闭或切换!");
}
@Override
public void onLoadingContent(WebView webview, String url) {
System.out.println("网页展示中!");
}
@Override
public void onError(WebView webview, ResourceRequest request, ResourceError error) {
super.onError(webview, request, error);
}
@Override
public ResourceResponse processResourceRequest(WebView webView, ResourceRequest request) {
return super.processResourceRequest(webView,request);
}
@Override
public boolean isNeedLoadUrl(WebView webview, ResourceRequest request) {
if (request == null || request.getRequestUrl() == null) {
return false;
}
Uri uri = request.getRequestUrl();
if (uri.getDecodedHost().equals(URL)) {
return false;
}
String url = request.getRequestUrl().toString();
if ( url.startsWith("http:") || url.startsWith("https:") ) {
return true;
} else {
return false;
}
}
public SetWebAgent(String URL) {
this.URL = URL;
}
}
3.2.3 StartWebView.java
package com.tdtxdcxm.hellowebview.webconfig;
import ohos.agp.components.webengine.ResourceRequest;
import ohos.agp.components.webengine.WebView;
public class StartWebView {
public static Boolean setwebviewstatus = false;
public static void startWebview(WebView webView,String url){
webView.getWebConfig().setJavaScriptPermit(true);
SetWebAgent setWebAgent = new SetWebAgent(url);
ResourceRequest request = null;
setWebAgent.isNeedLoadUrl(webView,request);
webView.setWebAgent(setWebAgent);
setwebviewstatus = true;
}
}
3.3 config.json
{
"app": {
"bundleName": "com.tdtxdcxm.hellowebview",
"vendor": "tdtxdcxm",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {
"default": {
"network": {
"cleartextTraffic": true
}
}
},
"module": {
"package": "com.tdtxdcxm.hellowebview",
"name": ".MyApplication",
"mainAbility": "com.tdtxdcxm.hellowebview.MainAbility",
"deviceType": [
"phone",
"tablet"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry",
"installationFree": false
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "unspecified",
"visible": true,
"name": "com.tdtxdcxm.hellowebview.MainAbility",
"icon": "$media:MyHelloWebView",
"description": "$string:mainability_description",
"label": "$string:entry_MainAbility",
"type": "page",
"launchType": "standard"
}
],
"reqPermissions": [
{
"name": "ohos.permission.GET_NETWORK_INFO"
},
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.SET_NETWORK_INFO"
},
{
"name": "ohos.permission.MANAGE_WIFI_CONNECTION"
},
{
"name": "ohos.permission.SET_WIFI_INFO"
},
{
"name": "ohos.permission.GET_WIFI_INFO"
}
],
"metaData": {
"customizeData": [
{
"name": "hwc-theme",
"value": "androidhwext:style/Theme.Emui.Light.NoTitleBar",
"extra": ""
}
]
}
}
}
3.4 三个string.json
3.4.1 element文件夹中的string.json
{
"string": [
{
"name": "entry_MainAbility",
"value": "HelloWebView"
},
{
"name": "mainability_description",
"value": "Java_Empty Ability"
},
{
"name": "mainability_HelloWorld",
"value": "Hello World"
},
{
"name": "mainability_webview",
"value": "Hello WebView"
},
{
"name": "webview_backbutton",
"value": "<<<"
},
{
"name": "webview_gobutton",
"value": ">>>"
}
]
}
3.4.2 en.element文件夹中的string.json
{
"string": [
{
"name": "entry_MainAbility",
"value": "HelloWebView"
},
{
"name": "mainability_description",
"value": "Java_Empty Ability"
},
{
"name": "mainability_HelloWorld",
"value": "Hello World"
},
{
"name": "mainability_webview",
"value": "Hello WebView"
},
{
"name": "webview_backbutton",
"value": "<<<"
},
{
"name": "webview_gobutton",
"value": ">>>"
}
]
}
3.4.3 zh.element文件夹中的string.json
{
"string": [
{
"name": "entry_MainAbility",
"value": "HelloWebView"
},
{
"name": "mainability_description",
"value": "Java_Empty Ability"
},
{
"name": "mainability_HelloWorld",
"value": "你好,世界"
},
{
"name": "mainability_webview",
"value": "Hello WebView"
},
{
"name": "webview_backbutton",
"value": "<<<"
},
{
"name": "webview_gobutton",
"value": ">>>"
}
]
}
4. app图标(MyHelloWebView.jpg)
5. app截图(远程真机调试运行)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南