深夜学习之 ReactNative 打开聊天窗口时,聊天记录如何始终保持底部
最近开发客服聊天功能,发现个没有思路的一个问题,如标题所述
1. 背景描述
现在有一个开始聊天界面,里面有个 FlatList 会先加载最近30条聊天记录,有文字、视频、图片,媒体文件还要请求宽高比动态给 width,height,点进来后先请求 API 拿到聊天记录(后面做了本地缓存)然后传给 FlatList 数据开始渲染,问题来了,渲染是从第一条开始的,也就是从顶部开始顺着往下依次渲染
2. 如何保持在最底部
聊天界面反向与传统列表,是最新的在最底部,历史是往上滑的,所以要一直 ref.current.scrollToEnd({animated: false}) 吗,以下我折腾过的几个思路
- setInterval 不停的 scrollToEnd(),直到用户触摸到屏幕我就不滚了,微信打开群聊消息也会这样,因为要加载媒体的宽高,页面自然就会跳动,– 但是要做分页,第一次不能加载太多,不然不停的滚啊滚
- 我不想滚🥹,假如我有50个聊天窗口(已经做了聊天记录缓存在本地),我就 map 50 个 FlatList,没打开某个聊天之前直接开始渲染,然后一直循环
[1]
的操作,做display: block
和display: hidden
,当然50个窗口默认display:hidden
,命中到哪个窗口我就display: block
出来,– 折腾半天发现根本行不通,数据流,数据指向,数据刷新逻辑写了三个Context都不够用,太特么复杂了… - 既然从上往下渲染,先把数据按照逆序排序,把 FlatList 旋转 180° 🤔,内容区域再 -180°不就正回来了🤔,往上滚不刚好可以触发滚动到底部加载更多🥰!! –实测可行,一点问题没有,就是滚动条会到左边,有强迫症或者强制需求的这个不是难事就不赘述了。
3. 放一些第[3]步成功的参考代码
<FlatList
ref={listRef}
data={list ?? []}
className={'px-3 rotate-180'} // 用的 nativewind 库直接写 className
onEndReached={() => console.log('触发滚动到底部,加载更多')}
onEndReachedThreshold={0.2}
renderItem={({item, index}) => <TouchableOpacity activeOpacity={1} onPress={() => setTaped(true)} className={'-rotate-180'}>
{item.user_id === user?.id ? <BubbleRight data={item} /> : <BubbleLeft data={item} />}
</TouchableOpacity>}
/>
本作品采用《CC 协议》,转载必须注明作者和本文链接
那个滑动条可以隐藏吧,这个思路好啊 :+1: