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

如何在Xamarin Forms中为ListView项添加动画效果

实现API加载列表项的首次入场动画方案

核心逻辑是通过状态标记或框架内置的过渡识别能力,仅给第一次渲染到DOM的新增列表项触发动画,避免后续重渲染、列表排序等操作重复触发动画效果。


原生JavaScript实现

  • 先定义入场动画样式,仅给携带指定类名的元素绑定动画
@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateX(-20px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
/* 仅带animated类的元素才会触发动画,默认只执行1次 */
.list-item.animated {
  animation: slideIn 0.3s ease forwards;
}
  • API请求拿到数据后,生成列表项DOM时临时添加动画类,动画执行完成后自动移除,避免后续DOM操作重复触发
async function loadList() {
  const res = await fetch('你的API接口地址')
  const listData = await res.json()
  const listContainer = document.querySelector('#list-container')
  
  listData.forEach(item => {
    const li = document.createElement('li')
    li.className = 'list-item animated'
    li.textContent = item.content
    // 单次绑定动画结束事件,执行后自动解绑
    li.addEventListener('animationend', () => {
      li.classList.remove('animated')
    }, { once: true })
    listContainer.appendChild(li)
  })
}

Vue3实现

直接用内置的<TransitionGroup>组件,依赖列表项的唯一key自动识别新增元素,仅对首次渲染的元素触发入场动画

<template>
  <TransitionGroup tag="ul" name="slide">
    <li v-for="item in list" :key="item.id" class="list-item">
      {{ item.content }}
    </li>
  </TransitionGroup>
</template>

<script setup>
import { ref } from 'vue'
const list = ref([])

async function loadList() {
  const res = await fetch('你的API接口地址')
  const data = await res.json()
  // 追加新数据,TransitionGroup会自动给新增项添加入场动画
  list.value.push(...data)
}
</script>

<style scoped>
.slide-enter-from {
  opacity: 0;
  transform: translateX(-20px);
}
.slide-enter-active {
  transition: all 0.3s ease;
}
</style>

React实现

借助react-transition-group库的过渡组件实现,逻辑和Vue一致,依赖唯一key区分已渲染/新增元素

import React, { useState, useEffect } from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';

function List() {
  const [list, setList] = useState([]);

  const loadList = async () => {
    const res = await fetch('你的API接口地址');
    const data = await res.json();
    setList(prev => [...prev, ...data]);
  };

  useEffect(() => {
    loadList();
  }, []);

  return (
    <ul>
      <TransitionGroup>
        {list.map(item => (
          <CSSTransition key={item.id} timeout={300} classNames="slide">
            <li className="list-item">{item.content}</li>
          </CSSTransition>
        ))}
      </TransitionGroup>
    </ul>
  );
}

对应样式参考:

.slide-enter {
  opacity: 0;
  transform: translateX(-20px);
}
.slide-enter-active {
  opacity: 1;
  transform: translateX(0);
  transition: all 0.3s ease;
}

注意:所有方案都不要用数组下标作为列表项的key,否则列表顺序变化时会出现动画误触发的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:54:01