当你辛苦的从网上爬下来一篇文章之后,怎么在你的应用内展示这些包含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 = "&lt;h1&gt;我是一个字符串&lt;/h1&gt;";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 = "&lt;h1&gt;我是一个字符串&lt;/h1&gt;";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[] { "&lt;h2&gt;我是一个有很多内容的html页面,真的很多。。。&lt;/h2&gt;"});}}

小结

以上介绍了使用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相关推荐

  1. 博客园客户端UAP开发随笔 -- App UI设计的三大纪律八项注意

    前言 每一个页面都是这个App的门面,尤其是主页面,看上去干净整洁清爽宜人容易操作,那么你的App就成功了一半.这也反映出了你这个开发团队的基本审美素质和设计理念.如果你不是一个团队,而是一个个人开发 ...

  2. 博客园客户端UAP开发随笔 -- 搭建App之间的桥梁

    开发Windows Phone应用的同学们应该都注意到了,Windows Phone 为了安全性,对应用的限制还是比较多的.我记得一位360的同学很无奈的说:WP太安全了,我们这些做WP上360卫士的 ...

  3. 博客园客户端UAP开发随笔 -- 适配不同尺寸的屏幕

    Windows 8诞生之初,Modern apps被设计在运行于全屏模式下.为了让Windows在运行Modern app时继续拥有前台多任务能力,Windows引入了一种全新的分屏技术"S ...

  4. 【完全开源】博客园客户端UWP版(上篇)

    目录 说明 PC截图 手机截图 关于源码 说明 这段时间一直在研究UWP开发,前段时间MS-UAP发布了淘宝UWP版,支持win10手机,看起来很叼.之后为了练手做了这个博客园客户端.目前只完成了一部 ...

  5. 【博客园客户端】博客园Android客户端正式发布

    原文地址为: [博客园客户端]博客园Android客户端正式发布 [最新消息]博客园Android客户端已经进驻官方Market,请各位园友果断给好评(手机Android Market中搜索" ...

  6. 用Qt写软件系列六:博客园客户端的设计与实现(1)

    引言 博客园是本人每日必逛的一个IT社区.尽管博文以.net技术居多,但是相对于CSDN这种业务杂乱.体系庞大的平台,博客园的纯粹更得我青睐.之前在园子里也见过不少讲解为博客园编写客户端的博文.不过似 ...

  7. 博客园客户端登录测试

    这是一个简单的博客园客户端登录,发送文章工具,主要用来测试socket通信,实现功能登录博客园,发表文章. 这是一个很简单的测试,未使用多线程,会有一种假死的现象,源码如下: 源码下载 1.登录界面 ...

  8. 用Office2010做博客园客户端

    关键字:Office2010发布cnblogs文章 原创啊,这个真的是原创的~~! 如何用Office2010作为博客园cnblogs的客户端: 1.打开Office2010,在"新建&qu ...

  9. 笔记-配置博客园客户端代码高亮(2016.08.20)

    参考博客文章:http://www.cnblogs.com/rollenholt/archive/2012/03/08/2384594.html 下载Window Live Writer 2012 最 ...

最新文章

  1. 两亿多用户,六大业务场景,知乎AI用户模型服务性能如何优化?
  2. 影响了一代代前端人的 20 个里程碑式的顶级开源项目!- 2006 - 2021
  3. Android 显示 WebView ,加载URL 时,向webview的 header 里面传递参数
  4. Qt Creator将QML模块与插件一起使用
  5. pc样式在ie8中的bug
  6. java解压服务器文件夹,java获取远程服务器上的文件夹
  7. 利用JS代码屏蔽指定地区访客浏览网站
  8. Flutter 即学即用系列博客——09 MethodChannel 实现原生与 Flutter 通信(二)
  9. APMServ5.2.6win10系统Apache、MySQL5.1启动失败解决办法
  10. Monkey命令参数详解
  11. PHP银行卡信息基类大全
  12. 遥感专业学c语言吗,2019遥感科学与技术专业怎么样、学什么、前景好吗
  13. 多线程1-Thread
  14. 控制台、操作台、调度台如何区分?
  15. windows64位jdk678网盘下载
  16. jvm设置http代理
  17. C#参数详解一(形参和实参)
  18. 【调剂】中科院自动化所医疗机器人课题组招收调剂研究生
  19. 达内不建议我学python-交钱了,学了3天Python编程,我想放弃了......
  20. 震惊科学界!DeepMind AI破解「蛋白质折叠」难题

热门文章

  1. ant文件放在ps的哪里_ant design vue按需导入icons
  2. 数学--数论--原根(循环群生成元)
  3. 数学--数论--HDU 2582 F(N) 暴力打表找规律
  4. 图论--SCC缩点--Tarjan
  5. Optical_Flow(2)
  6. javascript 正则表达式提取数字使用
  7. 参考文献_参考文献:
  8. 迁移学习 nlp_NLP的发展-第3部分-使用ULMFit进行迁移学习
  9. 邮件伪造_伪造品背后的数学
  10. 三星集团和华为集团,哪个更厉害?