关于React Native如何实现Android CoordinatorLayout效果

1,439 阅读3分钟

最近用RN重构一个较为复杂的原生页面,里面就用到了类似这种设计,如下图所示

example

对比一下能google得到的方案

首先分析一下github和各大内外网能google得到的blog里的方案,大部分跟我要的需求不一致,一部分用NativeComponent实现的,这就脱离了跨平台的初衷,一部分动画做的很差,Android端非常卡,目前为止看到最接近这种效果的是这位的博文 medium.com/@andi.gu.ca…

image.png

看源码可以知道是用的ScrollView嵌套TableView的方案,Demo里确实效果很完美,但是这个方案有两个致命的问题,

  • 一个是滑动偏移量,这种方案里,所有子tab的FlatList偏移量都随着父ScrollView变化而变化,当你在tab1滑动到商品10,然后你去到到tab2,加载出来的tab2仍然是停留在商品10的坐标,如果tab1与tab2数据长度不一致,但是这种方案里ScrollView整体高度却是一致的,就会导致数据少的tab,滑到商品底部后还能继续滑动,这种体验是绝对不能接受的
  • 一个是内存泄漏,在我的实际项目中FlatList的单个Item还是较为复杂的,会有图片,动画等等,因为FlatList被ScrollView包裹,它的内存回收机制会变得比较弱,在我的Android项目中滑动到70~80个item时,整个列表会突然变得异常卡顿,这个应该是RN的bug,不是单纯性能导致的,而且内存占用居高不下,测试几部Android旗舰机,中低端机,都有这个问题,但iOS没有这个突变卡顿的问题,内存问题一样存在

踩坑到这一步,时间已经过去了一周左右,本以为完美的方案,却还是有这么多致命的问题,但是基本得出结论,不能使用ScrollView嵌套FlatList的方案,然后切换回单层FlatList,顶部Header跟随FlatList偏移量做动画的方案

分解本项目现阶段实现的方案

demo
如上图所示,整个界面是一个FlatList,顶部需要做动画的地方通过设置contentContainerStyle的paddingTop来设置一个偏移量,这样我们就只用处理一个列表的滑动事件,其余元素跟随这个滑动手势做动画,这样既保证了flatList的内存回收机制,也避免了手势冲突的问题。

接下来要解决的就是一个scrollableTableView下的多个FlatList偏移量保持同步的问题(不保持同步会造成头部与FlatList之间偏移量异常的问题),这个问题比较简单,通过用一个数组,保存每个FlatList的Ref属性,然后在当前屏幕里的FlatList滑动手势结束时,同时设置其他FlatList的偏移量保持同步,但这样做的一个缺点是,无法记录每个页面的偏移量(应该可以实现,只是demo中未实现),然后要解决的是每一个FlatList初始化时,设置头部元素偏移量的问题,这个需要等到该FlatLis组件DidMount的时候设置,不然不会生效,大体实现思路就是这些,如有疑问欢迎指出讨论。

贴一下最终实现的源码:github.com/zjkhiyori/r…