WebView上显示加载框(5种方案) 原创 精华

没用的喵叔
发布于 2021-7-15 11:30
浏览
2收藏

@toc

方案5的效果图

WebView上显示加载框(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>

解决方案有以下几种:

  1. 用Dialog来显示,但是Dialog的特性,每次都得重新创建Dialog实例。见分支:dev_dialog

  2. 隐藏WebView,从而可以显示出view_loading。这种方案有一个的缺点,当html加载出,但是js或css还没加载完成,WebView还是隐藏的状态。只有所有资源都加载完成后,loadingView才隐藏,WebView才显示。所以,这种方案在感觉上页面加载很慢。但是,优点就是最靠谱。见分支:dev_hide_webview

    ComponentContainer 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);
        }
    }
    
  3. 创建一个Window,类型指定为WindowManager.LayoutConfig.MOD_TOAST来显示。本质上和第一种方法一样。见分支:dev_window

    ComponentContainer 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;
        }
    }
    
  4. 用Android View来显示,可以调用setVisibility来显示或隐藏。效果最好,但是用到了Android的View元素。可能将来在鸿蒙系统上不再支持。代码见:主分支。参考:简单配置,使用Android API开发鸿蒙应用

  5. 方案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
回复
举报
2条回复
按时间正序
/
按时间倒序
Whyalone
Whyalone

一个看似简单的问题,却是逃避不开的

回复
2021-7-15 13:43:41
没用的喵叔
没用的喵叔 回复了 Whyalone
一个看似简单的问题,却是逃避不开的

已经有三个相关的提问。所以,专门写一个帖子

1
回复
2021-7-15 14:00:49
回复
    相关推荐