用Flutter实现一个仿“探探”的左右滑动选择喜欢/不喜欢的效果

7,100

  写在前面,效果已经基本OK了,但是有些细节还没处理好。暂时主要有三个问题:

  • 用户手势到达屏幕边缘时释放,如果旋转角度过小,动画总感觉有些不流畅(也可能是我的错觉吧);
  • 给数据刷新提供的API还没想好,现在塞数据比较麻烦;
  • 因为UI设计是根据用户手势移动布局位置的,因此用户每次手势位置改变,都需要刷新布局,现在是用setState的方式去刷新的,不清楚在布局复杂的情况下是否会有性能问题。

  支持无限刷新。

代码:github.com/yumi0629/Fl…

效果图:

drag_like.gif

整体思路

  上层是一个支持用户手势监听的Widget,随着用户的手势进行平移+旋转变换;下层Widget虽然不支持手势监听,但是会接收上层布局的动画进度回调,进行放大,因此看起来也是跟随着手势的:   

  下层Widget在上层布局移出屏幕时,会缩小至原大小,缩小动画结束时,上下Widget的大小是一致的,因此此时直接将屏幕外的上层布局瞬间移回,用户在视觉上并不会察觉。此时的上层布局就是一个假的“第二层”,而原来的下层布局就变成了假的“第三层”,如此反复,形成了无限循环。

  要注意,因为有旋转动画的存在,上层布局的实际移动距离应该比控件左上角至屏幕右边缘的距离(右滑时)更大一些,具体为图中黑色标记的距离。但是,我并没有算的这么精确,实际移动距离选择了一个比较靠近的值(因为我觉得,问题不大~)。

什么时候刷新数据

  默认上层布局展示第1条数据,下层布局展示第2条数据;在上层布局移出屏幕时,就可以刷新上层布局,展示第2条数据了,对应的回调监听为onSlideCompleted;在下层布局缩小动画完成,上层布局瞬间移回原位置后,下层布局刷新数据,展示第3条数据,对应的回调监听为refreshBelow

底部喜欢/不喜欢图标的动画实现

  跟下层布局一样,也是接收上层布局动画的进度值,来实现随着用户手势而放大+改变颜色的效果。放大至峰值后,再自行进行一个缩小动画,缩小至原大小。

  上层监听用户手势的Widget,修改自之前写QQ侧滑菜单时的侧滑控件:Flutter:手把手教你实现一个仿QQ侧滑菜单的功能,怎么监听用户的手势在那篇文章里写的很清楚,就不赘述了。

  最后,感谢 Q群:Flutter中文用户组 中各位大佬对我的思路提点,给我提供了将上层布局直接移回,制作一个假的布局的方案,解决了困扰我很久的上层布局移出后该放在哪里的问题。