博客园客户端UAP开发随笔 -- App连接云端内容的桥梁:WebView
当你辛苦的从网上爬下来一篇文章之后,怎么在你的应用内展示这些包含HTML标记的文章?如果你使用的是Javascript开发应用,恭喜你,直接塞进页面就可以了,同时说明你很熟悉页面开发,而现在windows也支持这种方式。但是对于使用XAML开发的应用怎么办呢?我们还有WebView控件可以用。
越来越多的服务器端API返回的数据使用HTML了,所以我们也不得不对WebView多了解一些。
WebView有个Bug:放在Grid里时,最右侧有一个pixel缝隙时隐时现。要小心,别让PM抓住你的小辫子。另外,在一个App里大量使用WebView要小心内存。在Silverlight中,一个WebBrowser(不叫WebView)要占用大概30M吧,如果把Script disable掉可以省很多。在WinRT中情况就好多了,我开过6个WebView也就150M。
准备工作
WebView控件可以用来展示在线页面,应用内的离线页面,甚至是内存中拼接出来的html字符串也可以。下面我们介绍下这3个方式的使用:
首先在页面上添加一个WebView控件和3个按钮,这里需要注意的是,最好是吧WebView放在Grid中,因为这样WebView默认会填充整个区域,而在StackPanel中则不行。
<Pagex:Class="WebViewTest.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:WebViewTest"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"><Grid><Grid.RowDefinitions><RowDefinition Height="1*"></RowDefinition><RowDefinition Height="50"></RowDefinition></Grid.RowDefinitions><WebView x:Name="wv" Margin="10,20"/><StackPanel Grid.Row="1" Orientation="Horizontal"><Button x:Name="online" Click="online_Click">在线页面</Button><Button x:Name="offline" Click="offline_Click">应用文件</Button><Button x:Name="memory" Click="memory_Click">内存中</Button></StackPanel></Grid> </Page>
跑起来之后,我们的页面是下面的丑样子,这是因为我们还没加载内容。。。
展示在线页面
展示在线页面是最基本的需求了,使用这个功能,你就可以做一个自定义的浏览器了。。
这个功能实现非常简单,我们在online_Click中添加一行代码就可以了。
private void online_Click(object sender, RoutedEventArgs e){this.wv.Navigate(new Uri("http://www.microsoft.com"));}
如上面的代码,我们只需要调用WebView的Navigate方法,传入网页的地址即可。现在点击在线页面按钮,我们的应用有点浏览器的影子了。。
展示应用文件
通常我们会在应用内使用离线的页面文件来展示内容,比如一个帮助页面,或者用来展示内容的页面框架(这个之后会介绍)。
这个功能的实现其实使用的方法和在线是一样的,都是调用Navigate,只是在Uri上有区别,因为我们要使用的是应用内的文件,这里我们需要在构造Uri的时候,使用ms-appx-web这个Uri Scheme,更多关于Uri Scheme的内容,请点击这里。
private void offline_Click(object sender, RoutedEventArgs e){// ms-appx-web 表示我们要读取的是应用内的一个文件,并且是在Web区域,相对路径是Data/help.html, this.wv.Navigate(new Uri("ms-appx-web:///Data/help.html"));}
展示内存中字符串的内容
private void memory_Click(object sender, RoutedEventArgs e){var html = "<h1>我是一个字符串</h1>";this.wv.NavigateToString(html);}
和dom交互
使用WebView我们可以很方便的展示HTML页面,但是如果我们想要对dom做一些操作的话,还是需要使用javascript,比如调节字体大小,颜色等。这里用到的是InvokeScriptAsync方法,这个方法异步调用页面内指定的javascript方法。
首先为之前的帮助页面添加一个方法changeColor,用来修改h2的字体颜色:
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head><meta charset="utf-8" /><title></title><script>function changeColor(){document.getElementsByTagName("h2")[0].style.color = "red";}</script> </head> <body><h2>这是个帮助页面</h2><p>这里是帮助内容</p> </body> </html>
然后在主页面上添加一个按钮(方法同前,这里就略过了),在点击事件中调用这个方法:
private async void runCustomScript_Click(object sender, RoutedEventArgs e){// 第一个参数是页面内的方法名,第二个是传入的参数列表,这个例子没有用到,这里用来演示下怎么用await wv.InvokeScriptAsync("changeColor", new []{"arg1", "arg2"});}
点击之后,我们标题就红了。
在前面的代码中,其实存在一个潜在的问题,如果我们页面有点复杂,在dom还没有加载分析完成的时候,方法changeColor或标题可能还不存在,这样我们的调用不但不会有效果,还会引起异常。
所以需要在进行dom相关操作之前确认页面已经加载分析完成,WebView.DOMContentLoaded这个事件是在dom文档分析完成之后触发的,这样我们所有的dom操作就不会有错了。
public sealed partial class MainPage : Page{protected override void OnNavigatedTo(NavigationEventArgs e){}private void online_Click(object sender, RoutedEventArgs e){this.wv.Navigate(new Uri("http://www.microsoft.com"));}private void offline_Click(object sender, RoutedEventArgs e){// ms-appx-web 表示我们要读取的是应用内的一个文件,并且是在Web区域,相对路径是Data/help.html, this.wv.Navigate(new Uri("ms-appx-web:///Data/help.html"));}private void memory_Click(object sender, RoutedEventArgs e){var html = "<h1>我是一个字符串</h1>";this.wv.NavigateToString(html);}public MainPage(){this.InitializeComponent();this.NavigationCacheMode = NavigationCacheMode.Required;this.wv.DOMContentLoaded += wv_DOMContentLoaded;}// 我们新加入一个变量,用来标识当前页面是否分析完成bool domLoaded = false;void wv_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args){domLoaded = true;}private async void runCustomScript_Click(object sender, RoutedEventArgs e){if (domLoaded){// 第一个参数是页面内的方法名,第二个是传入的参数列表,这个例子没有用到,这里用来演示下怎么用await wv.InvokeScriptAsync("changeColor", new[] { "arg1", "arg2" });}}}
使用模板页
现在如果你把页面的内容加的更多一些的话,你会发现WebView有一小段时间是空白的,这个就是在页面分析渲染完成之前的间隙。。。
要解决这个问题,我们可以先让WebView加载下面这样一个很小的模板页。
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head><meta charset="utf-8" /><title></title><script>function setContent(content){var container = document.getElementById("container");container.innerHTML = content;}</script> </head> <body><div id="container"></div> </body> </html>
这个模板页里只有一个简单框架和一个用来填充内容的方法,因为模板页很小且是本地的,所以加载渲染的很快,不会有白色的闪烁。然后通过调用javascript方法来把内容写入到dom中。
private async void runCustomScript_Click(object sender, RoutedEventArgs e){if (domLoaded){await wv.InvokeScriptAsync("setContent", new[] { "<h2>我是一个有很多内容的html页面,真的很多。。。</h2>"});}}
小结
以上介绍了使用WebView的基本方法,还有一些别的技巧我们以后再说,比如调整成夜间模式,比如检测手势左右滑动,比如监测页面跳转......哎,有的公司就是靠这些技巧用WebView控件包装一下做了浏览器,但是可悲(或者可笑)的是,一些用户还在评论中说:不错,速度很快,流畅。除非有服务器端的数据压缩,否则能快到哪里去呢?
分享代码,改变世界!
Windows Phone Store App link:
http://www.windowsphone.com/zh-cn/store/app/博客园-uap/500f08f0-5be8-4723-aff9-a397beee52fc
Windows Store App link:
http://apps.microsoft.com/windows/zh-cn/app/c76b99a0-9abd-4a4e-86f0-b29bfcc51059
GitHub open source link:
https://github.com/MS-UAP/cnblogs-UAP
MSDN Sample Code:
https://code.msdn.microsoft.com/CNBlogs-Client-Universal-477943ab
转载于:https://www.cnblogs.com/ms-uap/p/4274484.html
博客园客户端UAP开发随笔 -- App连接云端内容的桥梁:WebView相关推荐
- 博客园客户端UAP开发随笔 -- App UI设计的三大纪律八项注意
前言 每一个页面都是这个App的门面,尤其是主页面,看上去干净整洁清爽宜人容易操作,那么你的App就成功了一半.这也反映出了你这个开发团队的基本审美素质和设计理念.如果你不是一个团队,而是一个个人开发 ...
- 博客园客户端UAP开发随笔 -- 搭建App之间的桥梁
开发Windows Phone应用的同学们应该都注意到了,Windows Phone 为了安全性,对应用的限制还是比较多的.我记得一位360的同学很无奈的说:WP太安全了,我们这些做WP上360卫士的 ...
- 博客园客户端UAP开发随笔 -- 适配不同尺寸的屏幕
Windows 8诞生之初,Modern apps被设计在运行于全屏模式下.为了让Windows在运行Modern app时继续拥有前台多任务能力,Windows引入了一种全新的分屏技术"S ...
- 【完全开源】博客园客户端UWP版(上篇)
目录 说明 PC截图 手机截图 关于源码 说明 这段时间一直在研究UWP开发,前段时间MS-UAP发布了淘宝UWP版,支持win10手机,看起来很叼.之后为了练手做了这个博客园客户端.目前只完成了一部 ...
- 【博客园客户端】博客园Android客户端正式发布
原文地址为: [博客园客户端]博客园Android客户端正式发布 [最新消息]博客园Android客户端已经进驻官方Market,请各位园友果断给好评(手机Android Market中搜索" ...
- 用Qt写软件系列六:博客园客户端的设计与实现(1)
引言 博客园是本人每日必逛的一个IT社区.尽管博文以.net技术居多,但是相对于CSDN这种业务杂乱.体系庞大的平台,博客园的纯粹更得我青睐.之前在园子里也见过不少讲解为博客园编写客户端的博文.不过似 ...
- 博客园客户端登录测试
这是一个简单的博客园客户端登录,发送文章工具,主要用来测试socket通信,实现功能登录博客园,发表文章. 这是一个很简单的测试,未使用多线程,会有一种假死的现象,源码如下: 源码下载 1.登录界面 ...
- 用Office2010做博客园客户端
关键字:Office2010发布cnblogs文章 原创啊,这个真的是原创的~~! 如何用Office2010作为博客园cnblogs的客户端: 1.打开Office2010,在"新建&qu ...
- 笔记-配置博客园客户端代码高亮(2016.08.20)
参考博客文章:http://www.cnblogs.com/rollenholt/archive/2012/03/08/2384594.html 下载Window Live Writer 2012 最 ...
最新文章
- 两亿多用户,六大业务场景,知乎AI用户模型服务性能如何优化?
- 影响了一代代前端人的 20 个里程碑式的顶级开源项目!- 2006 - 2021
- Android 显示 WebView ,加载URL 时,向webview的 header 里面传递参数
- Qt Creator将QML模块与插件一起使用
- pc样式在ie8中的bug
- java解压服务器文件夹,java获取远程服务器上的文件夹
- 利用JS代码屏蔽指定地区访客浏览网站
- Flutter 即学即用系列博客——09 MethodChannel 实现原生与 Flutter 通信(二)
- APMServ5.2.6win10系统Apache、MySQL5.1启动失败解决办法
- Monkey命令参数详解
- PHP银行卡信息基类大全
- 遥感专业学c语言吗,2019遥感科学与技术专业怎么样、学什么、前景好吗
- 多线程1-Thread
- 控制台、操作台、调度台如何区分?
- windows64位jdk678网盘下载
- jvm设置http代理
- C#参数详解一(形参和实参)
- 【调剂】中科院自动化所医疗机器人课题组招收调剂研究生
- 达内不建议我学python-交钱了,学了3天Python编程,我想放弃了......
- 震惊科学界!DeepMind AI破解「蛋白质折叠」难题