UWP 拉勾客户端
前些天, 用 Xamarin.Forms (XF) 将就着写了个拉勾的 UWP 和 Android 的客户端.
XF 对 Android 和 IOS 的支持做的很到位, 但是对 UWP 的支持目前仅限于预览版, "预留" 了很多BUG.
本想着等 Xamarin 团队尽快发部更新, 我好改掉这些 BUG, 但是苦等了个把月, 发部的 DLL 不但没有修改我所遇到的这些 BUG, 反而 BUG 越来越多了...
算鸟, 我也不等你了, 直接新开个项目, 直接写个 UWP 的...
源码
https://github.com/gruan01/Lagou.UWP
体验包
http://pan.baidu.com/s/1gei4V3l
安装步骤:
更新和安全->勾选开发人员模式-> 启用USB 和局域网连接,身份验证
然后在浏览器里输入手机上显示的地址,

点击 App Package 下面的那个按钮, 选择下载的 .appxbundle 文件 (你也可以用解压软件打开该文件, 里面包含 appx 文件).
点击 Go.
完成功能:
目前只写了 搜索 / 查看 / 及收藏到本地, 另外还有一个登陆查看简历的功能.
官方 app 中的 "发现" , 没有发现入口在哪里, 所以留白.
我的信息中, 除我的简历外, 其它都留白, 因为我没有可用数据可供调试.
已知 BUG :
登陆状态不准确.
截图:





问题与解决
1, Caliburn.Micro 和 NavigationCacheMode
如果页面的 NavigationCacheMode 设为 Enabled 或 Required, Caliburn.Micro 的 Message.Attach 会多次绑定, 导至事件处理方法被多次调用 (导航到其它页面, 在返回, 在导航,在返回, 问题就出来了).
除了等大神修复这个 BUG 外, 用 Command / Behavior / Attached Property 都可以解决这个问题.
2, 返回时, ListView 无法定位到离开之前的位置.
这个问题有两种解决办法:
a, 设置页面的 NavigationCacheMode 为 Enabled 或 Required.
b, 对于不方便使用 NavigationCascheMode 的页面, 参照 Windows-universal-samples 中的 ListView 相关的示例, 我写了一个 ListViewPositionRestoreBehavior:
https://github.com/gruan01/Lagou.UWP/blob/master/Lagou.UWP/Common/ListViewPositionRestoreBehavior.cs
具体就是在 ListView 的 UnLoad 事件中, 获取某个 item 的 Key (至于是哪个, 没有细研究), 这个 Key 由 ListView 每数据中的可以做唯一标识的数据编码而得.
在 ListView.Loaded 事件, 获取已存在的 Key, 还原出唯一标识, 然后根据这个标识找到相关的 item.
<ListView ItemsSource="{Binding Datas}">
<!--设置 Page 的 NavigationCacheMode 为 Enable 或 Required, 页面会被缓存,就不需要这个了 -->
<i:Interaction.Behaviors>
<common:ListViewPositionRestoreBehavior
Identity="{Binding KeyFinder}"
PersistedItemKey="{Binding PersistedItemKey, Mode=TwoWay}"
/>
</i:Interaction.Behaviors>
ViewModel:
#region used for ListView Position Restore
public Func<object, string> KeyFinder { get; set; }
= o => {
var item = (SearchedItemViewModel)o;
if (item != null) {
return item.Data.PositionId.ToString();
}
return string.Empty;
};
public string PersistedItemKey { get; set; }
#endregion
3, 图片
不得不说, 拉勾的 图片是专坑你流量的. 根本就没有经过优化 (至少在 WAP 版中是这样的), 随便找个公司的 LOGO, 都是 二三十K, 几百乘几百的分辨率, 在手机上根本就是浪费内存,别无它用.
浪费流量, 这个没有办法, 因为没有其它的图可用..
至于分辨率, 一开始, 我写了个 ThumbImageSource , 专门用于将大图改成小图, 但是运行发现有些多线程的问题没有处理好, 在 UWP 上又不比桌面环境, 有诸多限制, 对 UWP的整个 API 还不甚了解.
比如:
BitmapEncoder 居然无法写入 MemoryStream 转换出的 IRandomAccessStream , 用 StorageFile.OpenFile 生成的 IRandomAccessStream 却可以顺利写入..
不同的 BitmapPixelFormat 对应的 pixels bytes 数组大小还不一样, 又没有一个详细的文档说明...
网上搜索到贴子, 很多都是 WP 8.1 时代的 UAP 的 示例, UWP 并不适用...能写出以下代码, 真的是翻了好几天的贴子, 试了又试:
private async Task<Stream> CreateThumb(Stream orgStm, int width, int height, string filePath) {
var ras = orgStm.AsRandomAccessStream();
var wb = new WriteableBitmap(width, height);
ras.Seek();
await wb.SetSourceAsync(ras);
var stm = wb.PixelBuffer.AsStream(); //需要引用 System.Runtime.WindowsRuntime, NUGET 中有
var bytes = await stm.GetBytes();
using (var fs = await FileManager.Instance.Value.OpenFile(filePath)) {
//BitmapEncoder 无法写入 MemoryStream
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(
BitmapEncoder.JpegEncoderId,
fs);
encoder.BitmapTransform.ScaledWidth = (uint)width; // 最终的图片的大小
encoder.BitmapTransform.ScaledHeight = (uint)height;
//encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees;
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Straight,
(uint)wb.PixelWidth,
(uint)wb.PixelHeight,
96.0,
96.0,
bytes);
await encoder.FlushAsync();
return fs.CloneStream().AsStream();
}
}
最后, 放弃了 ThumbImageSource, 使用了这两个属性: DecodePixelHeight / DecodePixelWidth , 图片分辨的问题得以轻松解决,内存占用平滑多了!
<ImageBrush.ImageSource>
<BitmapImage UriSource="{Binding Data.CompanyLogoUri}"
DecodePixelHeight="
/>
</ImageBrush.ImageSource>
4, 消息订阅与发布
Xamarin.Forms 中实现了一个叫 MessagingCenter 的东西,方便在不同的页面中传递数据.
直接的 UWP项目, 当然不可能使用 Xamarin.Forms, 也就无从使用这个 MessagingCenter , 好在 Caliburn.Micro 也提供了这样一个机制, 省了不少事呢!
发布者:
a, 首先在事件聚合器中注册发布者:
public JobDetailViewModel(INavigationService ns, IEventAggregator eventAggregator) {
this._eventAggregator = eventAggregator;
this._eventAggregator.Subscribe(this);
....
b, 发布一个消息:
private async Task AddFavorite() {
await this._eventAggregator.PublishOnUIThreadAsync(this.Data);
}
接收者:
a, 同样也需要在事件聚合器中对接收者进行注册.
b, 接收消息, 需要实现 IHandle 事件:
public class LocalFavoriteViewModel : BasePageVM, IHandle<Position> {
....
....
public async void Handle(Position arg) {
var tip = "";
if (!this.Favorites.Any(f => f.PositionID == arg.PositionID)) {
var d = this.Convert(arg);
this.Datas.Add(new SearchedItemViewModel(d, this.NS));
this.AddToFavorite(arg);
......
}
------------------
OK ,完
欢迎 UWP 开发者共同完善这个 APP.
UWP 拉勾客户端的更多相关文章
- js 也来 - 【拉勾专场】抛弃简历!让代码说话!
前些日子谢亮兄弟丢了一个链接在群里,我当时看了下,觉得这种装逼题目没什么意思,因为每种语言都有不同的实现方法,你怎么能说你的方法一定比其他语言的好,所以要好的思路 + 好的语言特性运用才能让代码升华. ...
- 使用nodejs爬取拉勾苏州和上海的.NET职位信息
最近开始找工作,本人苏州,面了几家都没有结果很是伤心.在拉勾上按照城市苏州关键字.NET来搜索一共才80来个职位,再用薪水一过滤,基本上没几个能投了.再加上最近苏州的房价蹭蹭的长,房贷压力也是非常大, ...
- python3抓取到的拉勾数据统计
趁着最近有时间写了个拉勾爬虫抓取了后端.前端和移动端技术岗位的数据,总共大约6多万条记录,对其取前十名进行统计 按地域划分: 可以看出北上广深杭的数量远远超出其它城市,机会相对较多 2. 按融资阶段来 ...
- Python拉勾爬虫——以深圳地区数据分析师为例
拉勾因其结构化的数据比较多因此过去常常被爬,所以在其多次改版之下变得难爬.不过只要清楚它的原理,依然比较好爬.其机制主要就是AJAX异步加载JSON数据,所以至少在搜索页面里翻页url不会变化,而且数 ...
- 爬取拉勾部分求职信息+Bootstrap页面显示
今天在用python实现爬虫的时候,就想看一下用c#实现同样的功能到底会多出来多少code,结果写着写着干脆把页面也简单的写一个出来,方便调试, 大致流程如下: 1.分析拉勾数据 2.查找拉勾做了哪些 ...
- 网易考拉Android客户端网络模块设计
本文来自网易云社区 作者:王鲁才 客户端开发中不可避免的需要接触到访问网络的需求,如何把访问网络模块设计的更具有扩展性是每一个移动开发者不得不面对的事情.现在有很多主流的网络请求处理框架,如Squar ...
- 拉勾、Boss直聘、内推、100offer
BOSS直聘 拉勾.Boss直聘.内推.100offer
- rtmp直播拉流客户端EasyRTMPClient TCP窗口大小设计方法
EasyRTMPClient 简介 EasyRTMPClient是EasyDarwin流媒体团队开发.提供的一套非常稳定.易用.支持重连接的RTMPClient工具,以SDK形式提供,接口调用非常简单 ...
- python3 requests 获取 拉勾工作数据
#-*- coding:utf-8 -*- __author__ = "carry" import requests,json for x in range(1, 15): url ...
随机推荐
- MaskedTextBox的聚焦和光标位置
遇到一个关于MaskedTextBox聚焦和光标居左的问题. ①. 先说说聚焦: 起初给MaskedTextBox设置了Focus(),运行之后,并没有作用. 然后又给Form添加了Load事件,又设 ...
- Mysql数据库的通用安装方法
安装方式简介 Mysql数据库也时不时的用过一段时间,具体使用的功能都比较浅显,没有具体深入学习.最近一段在公司部署iNeedle系统时经常避免不了要安装apache和Mysql数据库.一般Mysql ...
- x01.os.7: 傻子一样的等
傻子一样的等 昨日出差,办完事后,下午 2:30,准备进长途汽车站买票回家,被一人拦住,说可以带我进去,车马上就要开了,买票来不及.我以为是汽车司机,就跟了进去.进去后,他打了个电话,说 3:30 车 ...
- hdu 5057 Argestes and Sequence(分块算法)
Argestes and Sequence Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- Django初体验(一):自定义表单提交
注:本人使用的Django1.8.3版本进行测试 除了使用Django内置表单,有时往往我们需要自定义表单.对于自定义表单Post方式提交往往会带来由CSRF(跨站请求伪造)产生的错误"CS ...
- 用FineReport做的共建共享填报系统
一.应用背景 随着信息技术的不断发展,快速开发出适合用户业务需求发展的填报报表是势在必然的,因此在不断的研究和分析下针对这一业务特点制作了此报表系统,以使不同开发商之间共建共享数据进行填报和统计分析的 ...
- 广州APP开发外包公司哪家比较好?广州达到信息技术有限公司技术到底怎么样?
广州APP开发公司哪家比较好,广州手机APP软件开发公司广州达到信息表示:用户的刚性需求是公司使用手机APP软件盈利的根本前提和基础,所以开发一款手机APP应用时必须从客户的角度来思考.因此公 ...
- DPM检测模型 VoC-release 5 linux 下编译运行
(转载请注明作者和出处 楼燚(yì)航的blog :http://www.cnblogs.com/louyihang-loves-baiyan/ 未经允许请勿用于商业用途) DPM目前使非神经网络方法 ...
- C#语句
C#控制语句 控制语句: goto语句 If语句 do while循环 for循环 while循环 switch语句 三元运算符 <test?><resultIfTrue&g ...
- Unity Camera的两种模式
http://www.cnblogs.com/zhaoqingqing/p/3302484.html