GVKun编程网logo

【MUI】5+ 预截原动画 打开webview案例(web截图插件)

14

对于想了解【MUI】5+预截原动画打开webview案例的读者,本文将是一篇不可错过的文章,我们将详细介绍web截图插件,并且为您提供关于android–在后台打开WebView、css–抑制WKWe

对于想了解【MUI】5+ 预截原动画 打开webview案例的读者,本文将是一篇不可错过的文章,我们将详细介绍web截图插件,并且为您提供关于android – 在后台打开WebView、css – 抑制WKWebView缩放内容,以与UIWebView相同的放大倍率渲染、flutter的webview案例、ios uiwebview wkwebview注意点小记的有价值信息。

本文目录一览:

【MUI】5+ 预截原动画 打开webview案例(web截图插件)

【MUI】5+ 预截原动画 打开webview案例(web截图插件)

讲几句

每次官方的案例不是太多,包括有段时间出世的plus.nativeObj.View
可以先看看官方的文章
plus.nativeObj.View解析
HTML5+ 官方 API

不说别的,咱们来看看官方人员的这一段解释

看起来很高大上啊!来来来,趁着晚上的时间折腾一下。

WebView截图

新建一个bitmap类型的变量(其实是原生的一种映射变量)

var bitmap = new plus.nativeObj.Bitmap('nwbitmap');//nwbitmap为bitmap的id

然后将webview内容绘制到Bitmap对象中

var ws = plus.webview.currentWebview();
    ws.draw(bitmap,function(){
        console.log('截屏绘制图片成功');
    },function(e){
        console.log('截屏绘制图片失败:'+JSON.stringify(e));
    });

为了能获取到每一个webview的截图,我们封装一下

//webview截图
        var drawWebView = function(webview,bitmap,callback) {
            bitmap = bitmap || new plus.nativeObj.Bitmap('defultBitMap');
            webview.draw(bitmap,function() {
                callback && callback(bitmap);
            },function(err) {
                callback && callback();
                console.log('截图错误:' + JSON.stringify(err))
            });
        }

原生动画

原生动画这块的资料太多,我这里不做多解释,大家可以查阅资料5+开始原生动画

//开始原生动画
        var startAnimation = function(type,callback) {
            plus.nativeObj.View.startAnimation({
                type: type || 'pop-in'//pop-in从右到左划入 pop-out从右到左划出
            },{},{
                bitmap: bitmap
            },function() {
                console.log('动画结束');
                callback && callback();
                //关闭原生动画 在这里我注释,选择在回调函数callback内处理
                //plus.nativeObj.View.clearanimation();
            });
        }

对比

直接上干货吧
app.js

var App = (function($) {
    var app = {};
    
    app.openWindow = function(url,id,op,data) {

        var nw = plus.webview.create(url,data),bitmap = new plus.nativeObj.Bitmap('nwbitmap');

        //开始原生动画
        var startAnimation = function(type,callback) {
            plus.nativeObj.View.startAnimation({
                type: type || 'pop-in'//默认
            },function() {
                console.log('动画结束');
                callback && callback();
                //关闭原生动画 
                //plus.nativeObj.View.clearanimation();
            });
        }

        //webview截图
        var drawWebView = function(webview,function(err) {
                callback && callback();
                console.log('截图错误:' + JSON.stringify(err))
            });
        }

        //webview onloaded事件
        nw.onloaded = function(e) {
            //开始截图open
            drawWebView(nw,function(bitmap) {
                if(!bitmap) {
                    nw.show('pop-in',300);
                    return;
                }
                //播放页面打开的动画
                startAnimation('pop-in',function() {
                    //动画播放完毕后
                    //显示webview
                    nw.show('none',function() {
                        //当webview关闭时
                        nw.onclose = function() {
                                //播放页面关闭动画
                                startAnimation('pop-out',function() {
                                    //关闭页面原生动画 
                                    plus.nativeObj.View.clearanimation();
                                });
                            }
                            //关闭页面原生动画 
                        plus.nativeObj.View.clearanimation();
                    })
                });

            });
        }
    }

    return app;
}(mui))

main.html

<!doctype html>
<html>

    <head>
        <Meta charset="UTF-8">
        <title></title>
        <Meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <link href="css/mui.min.css" rel="stylesheet" />
    </head>

    <body>
        <script src="js/mui.min.js"></script>
        <script src="js/app.js" ></script>
        <script>
            mui.init();
            mui.ready(function(){
                var url = '@R_301_5635@back.html';
                document.querySelectorAll("button")[0].addEventListener('tap',function(){
                    App.openWindow(url,'hehe');    
                });
                document.querySelectorAll("button")[1].addEventListener('tap',function(){
                    mui.openWindow(url,url,{
                         show:{
                            duration:300
                        },waiting:{
                            autoShow:false
                        }
                    });
                });
            });
        </script>
        <button type="button">截图方式 打开页面</button>
        <button type="button">MUI默认 打开页面</button>
    </body>

    <script>
    </script>

</html>

看看效果

可能动态图不是很清晰,在这里我总结一下
用预截图做动画打开webview 的方式 我简称 预截原动画
用默认webview的位移、渐变的效果打开webview 的方式 我简称 渐变帧动画

预截原动画
预截原动画是通过先把要打开的webview创建,然后监听onloaded事件,截一张webview的bitmap图 给 原生动画 调用
无疑这种方式的渲染打开是很稳的,然而可能是我代码逻辑问题,也可能是受webview默认的打开动画影响,在关闭时会瞬间闪屏。我也不多做解释。
预截原动画,真的很稳,打开新的页面,可以看得出,不掉帧,mui默认渐变帧动画的方式会稍微掉帧,如果页面dom js 复杂可能效果差异更大

渐变帧动画
渐变帧动画是给webview的位置以及样式作出调整,从而达到一个动画的目的,但是当你的页面dom复杂,js加载量大,尤其是图片加载较多的话,那么在这种方式的Webview动画就会掉帧啦

不过可以尝试截图原动画的方式去处理较复杂页面,否则,我们用了这么久的渐变帧动画完全够用了啦。

晚安,我要睡了,卧槽,这么晚了

返回动画修复

前面说过了,动态图也看到了,用预截原动画打开的页面,返回,也就是关闭的时候会闪屏一下,现在有新的解决方案,虽然马虎点

1)使用mui的预加载 新页面

2)截图新页面
截图成功就监听

loaded事件:为播放打开动画
show事件:为关闭动画
hide事件:再次截图新页面
![图片上传中...]
,并播放关闭动画,且播放完毕后,关闭页面,关闭动画

截图失败 就使用 渐变帧动画 打开新页面

js改动如下

var App = (function($) {
    var app = {};

    //开始原生动画
    function startAnimation(type,callback) {
        plus.nativeObj.View.startAnimation({
            type: type || 'pop-in' //默认
        },{
            bitmap: bitmap
        },function() {
            callback && callback(plus.nativeObj.View.clearanimation);
        });
    }

    //webview截图
    function drawWebView(webview,callback) {

        bitmap = bitmap || new plus.nativeObj.Bitmap('defultBitMap');
        webview.draw(bitmap,function() {
            callback && callback(bitmap);
        },function(err) {
            callback && callback();
            console.log('截图错误:' + JSON.stringify(err))
        });
    }

    app.openWindow = function(op) {
        if(op.id && plus.webview.getWebviewById(op.id)) {
            return;
        }
        var nw = $.preload(op),bitmap = new plus.nativeObj.Bitmap('nwbitmap');
        //webview onloaded事件
        nw.onloaded = function(e) {
            //开始截图open
            drawWebView(nw,function(bitmap) {
                if(!bitmap) {
                    //截图失败就降级用默认打开
                    nw.show('pop-in');
                    return;
                }
                nw.addEventListener('show',function() {
                    plus.nativeObj.View.clearanimation();
                })
                nw.addEventListener('hide',function() {
                    
                    drawWebView(nw,function(bitmap) {
                        if(!bitmap) {
                            //截图失败就降级用默认打开
                            nw.close('pop-out');
                            return;
                        }
                        //播放页面关闭动画
                        startAnimation('pop-out',function(close) {
                            nw.close();
                            //关闭页面原生动画 
                            close(); 
                        });
                        bitmap.clear();
                        bitmap = null;
                    });
                    
                })

                //播放页面打开的动画
                startAnimation('pop-in',function(close) {
                    //动画播放完毕后
                    //显示webview
                    nw.show('none');
                    //close();
                });

            });

        }

    }

    return app;
}(mui))

html页面多增加了几个图片,更好的对比渲染情况

<!doctype html>
<html>

    <head>
        <Meta charset="UTF-8">
        <title></title>
        <Meta name="viewport" content="width=device-width,function(){
                    App.openWindow({
                        url:url,id:'hehe'
                    });
                });
                document.querySelectorAll("button")[1].addEventListener('tap',{
                        waiting:{
                            autoShow:false
                        }
                    });
                });
            });
            
        </script>
        <button type="button">截图方式 打开页面</button>
        <button type="button">MUI默认 打开页面</button>
    </body>

    <script>
    </script>

</html>

效果图

效果图2.5m被吃了,尼玛 动态图

本文源码5+ 预截原动画

android – 在后台打开WebView

android – 在后台打开WebView

这是我第一次问什么,所以如果有什么不对的地方告诉我,我会尽快修复它.

我们有一位客户希望我们使用原生Android应用程序登录他们的服务器,但没有给我们一个自定义方式来执行此操作.他们希望我们使用他们必须登录的当前网站,并在进行身份验证后,在浏览器中检索包含我们所需数据的XML.之后,使用本机应用程序中的数据.所有这一切都是因为用户不知道/看到正在使用浏览器.一共乱了恕我直言.

当然,我过去从未尝试过这种方法,我的第一次测试让我觉得这是不可能的(或者非常困难).每当我尝试在隐藏的WebView中加载URL时,会弹出显示网站的默认浏览器.

我的主要问题是,是否可以加载webview并在后台使用它(调用javascript等…)?

谢谢.

解决方法

您可以将WebView默认设置为隐藏,其属性为android:visibility =“gone”,在运行时与其进行交互,然后在您加载数据后需要向用户显示时,只需调用setVisibility(View.VISIBLE)

希望这可以帮助!

css – 抑制WKWebView缩放内容,以与UIWebView相同的放大倍率渲染

css – 抑制WKWebView缩放内容,以与UIWebView相同的放大倍率渲染

问题

使用WKWebView代替UIWebView,我注意到WKWebView的内容大大缩小了与我的UIWebView。我想WKWebView停止这样做,只是尊重我的CSS值字面上,UIWebView的方式。

上下文

我在我的本地iOS应用程序中使用Web视图来显示信息内容的iPad上的popovers中的内容。这是伟大的能够给这个内容和设计人员说,“只是放入一些HTML内容,引用链接的CSS文件”。

所有这些工作只是伟大的,当使用UIWebView。

但是popovers通常是相当紧凑。

我经历了什么

在我的狭窄popovers,内容缩小,如果我的内容,整个网页被小型化适合。我可以看到WKWebView主要是为那些在iOS上构建替代浏览器或构建混合应用程序,其中WKWebView本质上,接管了屏幕。

WKWebView中的放大系数不是可以设置的。当然,用户可以放大,但是失败的目的。我不是在寻找放大视口;我正在寻找的整个内容适合和文字包装像它会与UIWebView。

使用WKWebView,在模拟器中,我会看到我想要的尺寸,如果我把我的身体文字大小增加到50px,而不是14px。这个代码,但是,甚至不能在设备上,所以膨胀我的CSS大小也不是一个选择!

UIWebView有什么问题?

好吧,没有什么真的。它不是(还)在iOS8中弃用,也许b / c它仍然有用,因为我体验。但我没有注意到,WKWebView是快。我看到一些猜测,写作是在墙上的UIWebView。我想:“为什么不在iOS8中采用更现代的API?

所以,我继续使用UIWebView现在,但我想切换到WKWebView,如果我可以得到它尊重我的CSS大小。

这里是我原来的CSS,UIWebView渲染得很好,但是WKWebView在一个popover将呈现在真正微小的字体:

body {
    font-family: "HelveticaNeue";
    font-size: 15px;
    line-height: 17px;
    color: #000000;
}

h1 {
    font-family: "HelveticaNeue-Bold";
    font-size: 18px;
    line-height: 20px;
    color: #000000;
}


h2 {
    font-family: "HelveticaNeue-Bold";
    font-size: 16px;
    line-height: 18px;
    color: #000000;
}

解决方法

我有同样的问题。我只是不得不放
<Meta name="viewport" content="initial-scale=1.0" />

进入我的标题块,为我解决了。看起来WKWebView的行为更像移动Safari比UIWebView,所以你需要设置视口,如果你想控制缩放或一般尺寸。

flutter的webview案例

flutter的webview案例

flutter 加载webview

安装插件  flutter_webview_plugin: ^0.2.1

从listview点击item跳转页面加载详情页案例

 

import ''dart:async'';
import ''package:flutter/cupertino.dart'';
import ''package:flutter/material.dart'';
import ''package:flutter_webview_plugin/flutter_webview_plugin.dart'';
 
/**
 * @Description  新闻网页,h5
 * @Author  zhibuyu
 * @Date 2018/10/19  9:09
 * @Version  1.0
 */
class NewsWebPage extends StatefulWidget{
  String  news_url;
  String title;
 
  NewsWebPage(this.news_url,this.title);
 
  @override
  State<StatefulWidget> createState()=>new NewsWebPageState(news_url,title);
 
}
class NewsWebPageState extends State<NewsWebPage>{
  String  news_url;
  String title;
  // 标记是否是加载中
  bool loading = true;
  // 标记当前页面是否是我们自定义的回调页面
  bool isLoadingCallbackPage = false;
  GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey();
  // URL变化监听器
  StreamSubscription<String> onUrlChanged;
  // WebView加载状态变化监听器
  StreamSubscription<WebViewStateChanged> onStateChanged;
  // 插件提供的对象,该对象用于WebView的各种操作
  FlutterWebviewPlugin flutterWebViewPlugin = new FlutterWebviewPlugin();
 
  NewsWebPageState(this.news_url, this.title);
 
  @override
  void initState() {
    onStateChanged = flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state){
      // state.type是一个枚举类型,取值有:WebViewState.shouldStart, WebViewState.startLoad, WebViewState.finishLoad
      switch (state.type) {
        case WebViewState.shouldStart:
        // 准备加载
          setState(() {
            loading = true;
          });
          break;
        case WebViewState.startLoad:
        // 开始加载
          break;
        case WebViewState.finishLoad:
        // 加载完成
          setState(() {
            loading = false;
          });
          if (isLoadingCallbackPage) {
            // 当前是回调页面,则调用js方法获取数据
            parseResult();
          }
          break;
      }
    });
  }
  // 解析WebView中的数据
  void parseResult() {
//    flutterWebViewPlugin.evalJavascript("get();").then((result) {
//      // result json字符串,包含token信息
//
//    });
  }
 
  @override
  Widget build(BuildContext context) {
    List<Widget> titleContent = [];
    titleContent.add(new Text(
     title,
      style: new TextStyle(color: Colors.white),
    ));
    if (loading) {
      // 如果还在加载中,就在标题栏上显示一个圆形进度条
      titleContent.add(new CupertinoActivityIndicator());
    }
    titleContent.add(new Container(width: 50.0));
    // WebviewScaffold是插件提供的组件,用于在页面上显示一个WebView并加载URL
    return new WebviewScaffold(
      key: scaffoldKey,
      url:news_url, // 登录的URL
      appBar: new AppBar(
        title: new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: titleContent,
        ),
        iconTheme: new IconThemeData(color: Colors.white),
      ),
      withZoom: true,  // 允许网页缩放
      withLocalStorage: true, // 允许LocalStorage
      withJavascript: true, // 允许执行js代码
    );
  }
 
  @override
  void dispose() {
    // 回收相关资源
    // Every listener should be canceled, the same should be done with this stream.
    onUrlChanged.cancel();
    onStateChanged.cancel();
    flutterWebViewPlugin.dispose();
    super.dispose();
  }
}

  

 

在跳转的地方调用

Navigator.of(widget.parentContext).push(

new MaterialPageRoute(builder: (context) {

return new NewsWebPage(link,tiltes,);//link,title为需要传递的参数

},

));

  

ios uiwebview wkwebview注意点小记

ios uiwebview wkwebview注意点小记

概述

wkwebview是苹果公司推出的替代uiwebview的方案,它在内存占用和稳定性方面有很大的优势,性能对比此篇文章就不讲了。
但是就目前情况而言,uiwebview还有有一些不能被完全替代的原因,比如wkwebview无法用NSURLProtocol拦截请求,因此无法通过NSURLProtocol实现加载离线化资源。
本文主要是记录自己在使用的时候碰到的一些坑。

方法注入

uiwebview目前的方式就是直接通过JS定义方法,然后使用JSC来获得JS方法的回调。
wkwebview可以直接使用addScriptMessageHandler来添加需要监听的方法,然后在userContentController中处理监听事件。
主要的区别是,uiwebview的注入只对当前界面生效,在加载新的url或者界面刷新后就会失效。而wkwebview的注入对整个wkwebview生效,界面刷新不会对其有影响。
所以在uiwebview上如果有注入全局方法的需求,通过直接运行JS代码注入不可行,一般可以使用拦截自定scheme和host的方式来做方法注入。

cookie

uiwebview的cookie与NSHTTPCookieStorage 同步,每次访问都会带上NSHTTPCookieStorage 中的内容,包括在页面中输入document.cookie也能获取到NSHTTPCookieStorage 中的cookie。

wkwebview不是及时同步

但是wkwebview的cookie和NSHTTPCookieStorage 就不能及时同步,注意是不能及时同步,并不是不同步。主要体现在以下两个方面:
1、当NSHTTPCookieStorage 的中的cookie被修改了,cookie是会同步到wkwebview的,但是不是及时同步的,比如说我修改了NSHTTPCookieStorage的值之后然后马上打开一个wkwebview,wkwebview不一定能获取到我刚刚修改的cookie。
2、当我使用document.cookie在wkwebview中设置cookie的时候,我当前设置的cookie是会回写到NSHTTPCookieStorage中,但是也不是及时的。

由于不及时同步,我们就说一下可能会有的问题,举例两个场景:
1、wkwebview没有获取到cookie,然后触发登陆逻辑后修改NSHTTPCookieStorage 跳回wkwebview,这时候wkwebview很有可能还是没有cookie的,因为wkwebview的cookie不是及时同步的。
2、某一模块为了满足自己的需求,修改了NSHTTPCookieStorage 中的一个cookie,而这个cookie刚好和其他模块重名了,由于wkwebview会回写cookie到NSHTTPCookieStorage 中,因此它会把原来这个名字的cookie给覆盖掉。而不仅仅存在cookie的value被修改,导致其他模块cookie错误的的问题,如果expire被修改了,也同时会给其他模块带去cookie过期的问题。

wkwebview对cookie的处理

目前网上的处理方法主要有以下两种:
1、在webview发起请求的时候附带cookie。
2、在webview创建的时候js注入cookie。

这两个方法都能解决wkwebview不能及时同步NSHTTPCookieStorage 的问题,但是无法解决wkwebview的cookie修改后不能及时回写到NSHTTPCookieStorage 的问题。
还是举个例子:
第一个wkwebview中的JS修改了一段cookie之后,没过多久又打开了第二个wkwebview,第二个wkwebview是很可能获取不到第一个wkwebview对cookie的修改的。最根本原因就是由于wkwebview的cookie无法及时回写到NSHTTPCookieStorage 。

那么这种情况如何解决呢?答案就是wkProcessPool。

WKProcessPool

使用同一个WKProcessPool的wkwebview可以共享cookie数据,但是WKProcessPool中的cookie并不和NSHTTPCookieStorage 一样会本地存储。在APP重启后WKProcessPool中的cookie会被重置。

cookie仍然存在的问题

1、 第一个wkwebview中的JS修改了一段cookie之后,没过多久又打开了一个uiwebview,uiwebview如何能及时同步到wkwebview对cookie的修改?
2、如果某个模块在wkwebview中修改了cookie的值,导致NSHTTPCookieStorage 中的cookie被篡改或者过期,如何定位到该模块的问题?

关于【MUI】5+ 预截原动画 打开webview案例web截图插件的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于android – 在后台打开WebView、css – 抑制WKWebView缩放内容,以与UIWebView相同的放大倍率渲染、flutter的webview案例、ios uiwebview wkwebview注意点小记等相关内容,可以在本站寻找。

本文标签: