WebView上显示加载框(5种方案) 原创 精华
没用的喵叔
发布于 2021-7-15 11:30
浏览
2收藏
@toc
方案5的效果图
问题现状
不管WebView在布局中哪个层级,都在最顶层显示。如下布局view_loading
会被webview遮挡。
<?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:alignment="center"
ohos:orientation="vertical">
<ProgressBar
ohos:id="$+id:progressbar"
ohos:height="5vp"
ohos:progress_width="5vp"
ohos:max="100"
ohos:progress="10"
ohos:width="match_parent"
ohos:progress_color="#47CC47"/>
<DependentLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:stack_layout"
ohos:height="match_parent"
ohos:width="match_parent">
<ohos.agp.components.webengine.WebView
ohos:id="$+id:webview"
ohos:height="match_parent"
ohos:width="match_parent"/>
<include
ohos:height="110vp"
ohos:width="110vp"
ohos:center_in_parent="true"
ohos:layout="$layout:view_loading"/>
</DependentLayout>
</DirectionalLayout>
解决方案有以下几种:
-
用Dialog来显示,但是Dialog的特性,每次都得重新创建Dialog实例。见分支:dev_dialog
-
隐藏WebView,从而可以显示出
view_loading
。这种方案有一个的缺点,当html加载出,但是js或css还没加载完成,WebView还是隐藏的状态。只有所有资源都加载完成后,loadingView才隐藏,WebView才显示。所以,这种方案在感觉上页面加载很慢。但是,优点就是最靠谱。见分支:dev_hide_webviewComponentContainer loadingView = (ComponentContainer) findComponentById(ResourceTable.Id_loadingView); private void showLoading() { if(loadingView !=null){ mWebView.setVisibility(Component.HIDE); loadingView.setVisibility(Component.VISIBLE); } } private void hideLoading() { if(loadingView!=null){ mWebView.setVisibility(Component.VISIBLE); loadingView.setVisibility(Component.HIDE); } }
-
创建一个Window,类型指定为
WindowManager.LayoutConfig.MOD_TOAST
来显示。本质上和第一种方法一样。见分支:dev_windowComponentContainer progressBarDlg = (ComponentContainer) LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_view_loading, null, false); private Window add2window(ComponentContainer progressBarDlg) { try { Window window = WindowManager.getInstance().addComponent(progressBarDlg, getContext(), WindowManager.LayoutConfig.MOD_TOAST); WindowManager.LayoutConfig layoutConfig = new WindowManager.LayoutConfig(); layoutConfig.width = progressBarDlg.getLayoutConfig().width; layoutConfig.height = progressBarDlg.getLayoutConfig().height; window.setLayoutConfig(layoutConfig); return window; } catch (Exception e) { e.printStackTrace(); L.i(TAG, e.getMessage()); } return null; }
private void showLoading() { if(dlgWindow==null && getLifecycle().getLifecycleState()== Lifecycle.Event.ON_ACTIVE){ dlgWindow = add2window(progressBarDlg); } } private void hideLoading() { if(dlgWindow!=null){ try { WindowManager.getInstance().destroyWindow(dlgWindow); } catch (Exception e) { } dlgWindow=null; } }
-
用Android View来显示,可以调用setVisibility来显示或隐藏。效果最好,但是用到了Android的View元素。可能将来在鸿蒙系统上不再支持。代码见:主分支。参考:简单配置,使用Android API开发鸿蒙应用
-
方案5是对方案4的优化
回答了一个问题,题主顺便也分享了他的最终实现:https://developer.huawei.com/consumer/cn/forum/topic/0202621839353600065
主要代码:
public static void bringToFront() {
Activity activity = getCurrentActivity();
FrameLayout decorView = (FrameLayout) activity.getWindow().getDecorView();
FrameLayout contentView = decorView.findViewById(R.id.content);
FrameLayout frameLayout = (FrameLayout) contentView.getChildAt(0);//和WebView并列在contentView下面
SurfaceView agpContainerView = (SurfaceView) frameLayout.getChildAt(0);
agpContainerView.setZOrderOnTop(true);
agpContainerView.getHolder().setFormat(PixelFormat.TRANSPARENT);
}
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-7-29 14:16:59修改
赞
4
收藏 2
回复
相关推荐
一个看似简单的问题,却是逃避不开的
已经有三个相关的提问。所以,专门写一个帖子