碰肩
2021-02|商业项目
一款基于地理位置的陌生人近场社交应用查看
项目简介
这是一款陌生人社交 APP,通过手机定位,帮助人们找回擦肩而过的人和精彩瞬间,鼓励人们积极探索身边发生的新鲜事物,与有趣的人一起,开启一段妙不可言的缘分之旅。
项目预览
首页 | 擦肩 |
---|---|
瞬间 | 我的 |
幕后花絮
这是由我一个人独立负责前端开发,从零到一上架到应用商店的首个社交应用。
为了给用户带来最丝滑、有温度的社交体验,我们不断打磨交互设计与动画细节。尤其在地图交互上,做了许多巧思和创新,带来更有趣的地图交互体验。
期间,我在掘金个人专栏发表了 10 余篇 Flutter 相关的技术文章,记录分享开发过程中遇到的一些有趣问题,累计阅读量 50,000+。
作为一名开源爱好者,我也为许多 Flutter 开源项目做过贡献,包括作为 GetX(最受 Flutter 开发者喜爱的库) 的首位中文文档翻译者,以及为 flutter_screenutil, image 等常用库提交过 PR。
此外,我还发布维护了一些 package 回馈给社区,包括: nested_scroll_view_plus, auto_hide_keyboard 等。
技术浅析
该项目使用 Flutter 跨平台开发,具有良好的 UI 和性能表现,非常适合早期项目多平台快速开发迭代。
在此项目中,我的主要贡献如下:
1. 基于高德地图的后台定位
手机定位是本应用的核心模块,如何保持定位的精确、稳定和低功耗至关重要,尤其是在室内、地下(地铁)和后台持续定位等场景。
这里我们选择了高德定位SDK,相较于系统原生的 GPS 定位服务,它采用 GPS + 北斗 + 基站(含5G基站)+ WIFI 的混合定位模式,可以根据设备所处环境,智能选择最佳的定位方式,在降低耗电的同时,兼顾定位的准确性。
在应用启动后,会注册并启动一个后台定位服务,通过注册地理围栏,触发回调后进行一次高精度定位,然后继续以当前位置为半径,注册下一个地理围栏回调
的方式,实现后台定位持续、稳定、低功耗和高精度的需要1。
此外,当后台定位服务获取到最新位置更新时,会启动一个 Flutter Headless Engine
,然后将在原生平台获取到的定位数据,发送到预先注册的 Dart 回调函数中,复用 Flutter 端已有的网络请求模块和其他的业务逻辑。
2. 增强的 NestedScrollView
在主流 APP 中有一种常见的布局,经常用在「我的」页面。这种布局通常由 header + body 两部分组成。其中头部高度一般不固定,用来展示用户头像和个人简介等信息,而 body 区域则是由不同标签分类组成的 Tabview,里面是用来展示用户作品和动态等信息的内容列表。
抖音 | 小红书 |
---|
在 Flutter 中有一个组件与此布局十分相似,那就是 NestedScrollView
。不过遗憾的是 NestedScrollView
在向下滑动时,只有内部的 TabView 列表会被下拉刷新(过度滚动),而不是像抖音和小红书那样外部的 header 会被下拉刷新。
NestedScrollView | NestedScrollViewPlus |
---|
为了解决这个问题,我 Fork 了官方的 NestedScrollView
,然后重写了内外 ScrollView 和 Coordinator 坐标之间的映射关系,并修复了一些已知问题。
你可以在 pub.dev 上搜索使用修改后的 NestedScrollViewPlus
组件,轻松实现类似抖音和小红书的个人主页布局。
3. 使用 Flutter Widget 作为地图 Marker
在常见的 Flutter 地图方案中,大多数是将原生平台的地图视图,直接嵌入到 Flutter 界面,造成了原生地图视图与 Flutter 视图的隔离,无法直接使用 Flutter 组件作为地图覆盖物。
工单反馈有趣的是高德地图、百度地图等插件,都提供了使用静态图片素材作为地图覆盖物的功能,能够基本解决静态 Marker 效果的需求。但是对于更复杂的动态效果(比如交互动画等),却又无能为力。
既然无法直接将 Flutter 中的组件“塞”到原生地图上,那么反过来,能不能在 Flutter 视图上将组件“绑定”到原生地图上呢?
理论上是可行的:只需要获取到地图的经纬度边界,通过墨卡托投影2,将经纬坐标映射到屏幕坐标,即可实现“绑定” Flutter 组件到地图上的效果。
为此,我在高德地图插件的基础上,实现了使用 Flutter 原生 Widget 作为地图 Marker,为传统的地图交互体验,带来了更多的想象空间。