欢迎关注微信大众号:FSA全栈举动

系列文章

开源库: flutter_scrollview_observer

  1. Flutter – 获取ListView当时正在显现的Widget信息
  2. Flutter – 列表翻滚定位超强辅助库,墙裂引荐!
  3. Flutter – 快速完成谈天会话列表的作用,完美

一、方针作用

谈天会话页的列表作用

  • 1、谈天数据不满一屏时,顶部显现一切谈天数据
  • 2、刺进音讯时
    • 假如最新音讯紧靠列表底部时,则刺进音讯会使列表向上推
    • 假如不是紧靠列表底部,则固定到当时谈天位置

作用如图所示:

二、原理

1、 触及的办法

ScrollPhysics 提供了 adjustPositionForNewDimensions 办法,用于批改 ScrollViewrebuild 后的偏移量,办法声明如下

double adjustPositionForNewDimensions({
  required ScrollMetrics oldPosition,
  required ScrollMetrics newPosition,
  required bool isScrolling,
  required double velocity,
})

默认情况下,值为上一次的偏移量,即 newPosition 参数的 pixels,所以在顶部刺进音讯时,音讯列表就会跟从翻滚。

如下图所示,调查蓝色的音讯条目,每播入一条音讯时,一切音讯会自动往上顶,而翻滚视图的偏移量其实一直是没有变化的~

注:值得注意的是,假如该办法回来的值与 newPositionpixels 不相等时,则会触发视图的重新布局,所以这个操作仍是比较昂贵的,应尽量减少回来值的变化。

2、完成逻辑

根据上述内容咱们不难推出刺进音讯时的作用完成原理如下:

作用 回来的值
音讯紧靠列表底部时,刺进音讯会使列表向上推 直接回来 super 的值,即 newPosition 参数的 pixels
假如不是紧靠列表底部,则固定到当时谈天位置 回来原本第 0 条音讯的最新偏移量

下面要点说明一下第 2 点中 回来原本第0条音讯的最新偏移量 的完成逻辑:

ListView 的实质是 RenderSliverList,经过 RenderSliverListfirstChild 属性拿到当时列表中烘托的首个 item

如下图,firstChild 是下标为 10item,这个 item 与预烘托区域 cacheExtent 相关,假如将其设置为 0,则 firstChild 的下标将会是 12,这个相信不难理解。

Flutter - 快速实现聊天会话列表的效果,完美

所以,咱们只需要在刺进音讯时,记录第 0 条音讯的偏移量,当列表视图 rebuild 后,adjustPositionForNewDimensions 办法会被调用,此时取出第 1 条音讯的偏移量,两者的差值加上 super 的值即为方针批改偏移量。

至于 谈天数据不满一屏时,顶部显现一切谈天数据 这个作用只是在切换 shrinkWrap 而已,比较简单就不在此打开讲了。

我已将上述逻辑进行了封装,集成于 flutter_scrollview_observer,接下来咱们就来看看怎么运用。

三、运用

现在只需三个过程即可快速完成谈天会话列表的作用

过程一:初始化必要的 ListObserverControllerChatScrollObserver

/// 初始化 ListObserverController
observerController = ListObserverController(controller: scrollController)
  ..cacheJumpIndexOffset = false;
/// 初始化 ChatScrollObserver
chatObserver = ChatScrollObserver(observerController)
  ..toRebuildScrollViewCallback = () {
    // 这儿能够重建指定的翻滚视图即可
    setState(() {});
  };

过程二:按如下装备 ListView 并运用 ListViewObserver 将其包裹

Widget _buildListView() {
  Widget resultWidget = ListView.builder(
    physics: ChatObserverClampinScrollPhysics(observer: chatObserver),
    shrinkWrap: chatObserver.isShrinkWrap,
    reverse: true,
    controller: scrollController,
    ...
  );
  resultWidget = ListViewObserver(
    controller: observerController,
    child: resultWidget,
  );
  return resultWidget;
}

过程三:刺进或删去音讯前,调用 ChatScrollObserverstandby 办法

onPressed: () {
  chatObserver.standby();
  setState(() {
    chatModels.insert(0, ChatDataHelper.createChatModel());
  });
},
...
onRemove: () {
  chatObserver.standby(isRemove: true);
  setState(() {
    chatModels.removeAt(index);
  });
},

注:示例中的 setState 都能够换成对列表视图进行局部刷新的代码

四、最后

GitHub地址: flutter_scrollview_observer

该库还完成了其它十分实用的功用,相关功用有对应的文章进行叙说

相关文章链接:

  • Flutter – 列表翻滚定位超强辅助库,墙裂引荐!
  • Flutter – 获取ListView当时正在显现的Widget信息

假如这个库对你很有帮助,请不惜给个 star

假如文章对您有所帮助, 请不惜点击关注一下我的微信大众号:FSA全栈举动, 这将是对我最大的激励. 大众号不只有 iOS 技术,还有 AndroidFlutterPython 等文章, 可能有你想要了解的技术知识点哦~

Flutter - 快速实现聊天会话列表的效果,完美