You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android:如何实现RecyclerView与LazyColumn的定向列表项动画?

实现滚动方向反向的列表项动画效果

核心思路

实现该效果的核心是判断列表的滚动方向,并根据方向给新进入视口或插入的列表项分配反向动画逻辑:向上滚动时列表项从上方滑入(视觉上向下展开),向下滚动时从下方滑入(视觉上向上展开),同时结合高度过渡与渐显效果。


具体实现步骤

1. 监听滚动方向

通过记录上一次滚动位置,与当前位置对比判断滚动方向:

let prevScrollTop = 0;
const listContainer = document.getElementById('list-container');

listContainer.addEventListener('scroll', () => {
  const currentScrollTop = listContainer.scrollTop;
  window.scrollDirection = currentScrollTop > prevScrollTop ? 'down' : 'up';
  prevScrollTop = currentScrollTop;
});

2. 定义CSS动画与基础样式

设置列表项初始隐藏状态,以及两种方向的滑入+高度展开动画:

#list-container {
  height: 400px;
  overflow-y: auto;
}

.list-item {
  overflow: hidden;
  opacity: 0;
  height: 0;
  margin: 8px 0;
  padding: 12px;
  background: #f5f5f5;
  border-radius: 4px;
  transition: height 0.3s ease;
}

/* 向上滚动时:列表项从上方滑入(向下展开) */
@keyframes slideDownIn {
  from {
    transform: translateY(-100%);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

/* 向下滚动时:列表项从下方滑入(向上展开) */
@keyframes slideUpIn {
  from {
    transform: translateY(100%);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.active.slide-down {
  animation: slideDownIn 0.3s ease forwards;
  height: auto;
}

.active.slide-up {
  animation: slideUpIn 0.3s ease forwards;
  height: auto;
}

3. 检测视口内列表项并触发动画

使用IntersectionObserver监听列表项是否进入视口,根据滚动方向添加对应动画类:

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const item = entry.target;
      item.classList.add('active', window.scrollDirection === 'up' ? 'slide-down' : 'slide-up');
      observer.unobserve(item);
    }
  });
}, { root: listContainer });

// 初始化监听现有列表项
document.querySelectorAll('.list-item').forEach(item => {
  observer.observe(item);
});

4. 处理新项插入逻辑

动态插入新项时,根据滚动方向选择插入位置,再交给观察者监听:

function addNewItem(content) {
  const newItem = document.createElement('div');
  newItem.className = 'list-item';
  newItem.textContent = content;
  
  // 向上滚动时插顶部,向下滚动时插底部
  if (window.scrollDirection === 'up') {
    listContainer.prepend(newItem);
  } else {
    listContainer.append(newItem);
  }
  observer.observe(newItem);
}

关键细节

  • 滚动方向判断要绑定在列表容器的scroll事件上,避免全局滚动干扰
  • 高度过渡与位置偏移动画分开处理,保证展开与滑入效果同步
  • 动态插入项的位置要匹配滚动方向,确保动画逻辑符合视觉预期

内容的提问来源于stack exchange,提问作者Tan Telephone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 22:25:01