ListViewAnimations开源项目安装与使用指南
2026-01-18 10:14:38作者:裘旻烁
概述
ListViewAnimations是一个功能强大的Android开源库,专门为ListView、GridView等AbsListView提供丰富的动画效果和交互操作。尽管项目已标记为DEPRECATED(已弃用),推荐使用RecyclerView解决方案,但对于仍在维护旧项目的开发者来说,这个库仍然是一个非常有价值的工具。
核心特性
ListViewAnimations提供以下核心功能:
| 功能模块 | 描述 | 适用场景 |
|---|---|---|
| 外观动画 | 提供多种入场动画效果 | 列表项动态展示 |
| 滑动删除 | 支持滑动删除和撤销操作 | 邮件、待办事项应用 |
| 拖拽排序 | 实现列表项拖拽重新排序 | 任务管理、图片排序 |
| 动态添加 | 支持动画方式添加新项目 | 实时数据更新场景 |
| 扩展显示 | 点击展开显示更多内容 | 详情展示、评论列表 |
环境要求与安装
系统要求
- Android API Level 8+ (Android 2.2+)
- Gradle构建系统
- Android Studio开发环境
Gradle依赖配置
在项目的build.gradle文件中添加以下依赖:
repositories {
mavenCentral()
}
dependencies {
// 核心动画模块
compile 'com.nhaarman.listviewanimations:lib-core:3.1.0@aar'
// 操作功能模块(包含核心模块)
compile 'com.nhaarman.listviewanimations:lib-manipulation:3.1.0@aar'
// 粘性列表头扩展模块
compile 'com.nhaarman.listviewanimations:lib-core-slh:3.1.0@aar'
}
Maven依赖配置
对于使用Maven的项目,在pom.xml中添加:
<dependencies>
<dependency>
<groupId>com.nhaarman.listviewanimations</groupId>
<artifactId>lib-core</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.nhaarman.listviewanimations</groupId>
<artifactId>lib-manipulation</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.nhaarman.listviewanimations</groupId>
<artifactId>lib-core-slh</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
手动JAR包安装
-
下载所需的JAR文件:
- lib-core-3.1.0.jar
- lib-manipulation-3.1.0.jar
- lib-core-slh-3.1.0.jar
- NineOldAndroids.jar(动画支持库)
-
将JAR文件复制到项目的
libs目录 -
在IDE中添加为外部库依赖
基本使用教程
1. 基础动画适配器使用
// 创建基础适配器
BaseAdapter baseAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
// 创建动画适配器(淡入效果)
AnimationAdapter animAdapter = new AlphaInAnimationAdapter(baseAdapter);
animAdapter.setAbsListView(listView);
// 设置到ListView
listView.setAdapter(animAdapter);
2. 内置动画效果
ListViewAnimations提供多种内置动画效果:
// 淡入动画
new AlphaInAnimationAdapter(baseAdapter);
// 从左侧滑入动画
new SwingLeftInAnimationAdapter(baseAdapter);
// 从右侧滑入动画
new SwingRightInAnimationAdapter(baseAdapter);
// 从底部滑入动画
new SwingBottomInAnimationAdapter(baseAdapter);
// 缩放动画
new ScaleInAnimationAdapter(baseAdapter);
// 组合动画(先右侧滑入再底部滑入)
new SwingBottomInAnimationAdapter(
new SwingRightInAnimationAdapter(baseAdapter)
);
3. 动态列表操作示例
public class DynamicListActivity extends Activity {
private DynamicListView mListView;
private ArrayAdapter<String> mAdapter;
private int mNewItemCount = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_list);
mListView = (DynamicListView) findViewById(R.id.listview);
// 创建适配器
mAdapter = new ArrayAdapter<String>(this, R.layout.list_item, new ArrayList<String>());
for (int i = 0; i < 10; i++) {
mAdapter.add("Item " + i);
}
// 添加动画效果
AlphaInAnimationAdapter animAdapter = new AlphaInAnimationAdapter(mAdapter);
animAdapter.setAbsListView(mListView);
mListView.setAdapter(animAdapter);
// 启用拖拽功能
mListView.enableDragAndDrop();
mListView.setDraggableManager(new TouchViewDraggableManager(R.id.drag_handle));
// 启用滑动删除
mListView.enableSimpleSwipeUndo();
// 设置项目移动监听器
mListView.setOnItemMovedListener(new OnItemMovedListener() {
@Override
public void onItemMoved(int originalPosition, int newPosition) {
Toast.makeText(DynamicListActivity.this,
"Moved: " + mAdapter.getItem(newPosition), Toast.LENGTH_SHORT).show();
}
});
// 设置项目点击添加新项
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mListView.insert(position, "New Item " + (mNewItemCount++));
}
});
}
}
高级功能配置
1. 自定义动画适配器
public class CustomAnimationAdapter extends AnimationAdapter {
public CustomAnimationAdapter(BaseAdapter baseAdapter) {
super(baseAdapter);
}
@NonNull
@Override
public Animator[] getAnimators(@NonNull ViewGroup parent, @NonNull View view) {
// 创建自定义动画效果
Animator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 0.5f, 1.0f);
Animator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 0.5f, 1.0f);
Animator rotation = ObjectAnimator.ofFloat(view, "rotation", 0, 360);
scaleX.setDuration(300);
scaleY.setDuration(300);
rotation.setDuration(600);
return new Animator[]{scaleX, scaleY, rotation};
}
}
2. 滑动删除与撤销功能
// 创建滑动删除回调
OnDismissCallback dismissCallback = new OnDismissCallback() {
@Override
public void onDismiss(@NonNull ViewGroup listView, @NonNull int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
mAdapter.remove(position);
}
}
};
// 创建撤销适配器
SimpleSwipeUndoAdapter undoAdapter = new SimpleSwipeUndoAdapter(mAdapter, this, dismissCallback);
// 设置动画效果
AnimationAdapter animAdapter = new AlphaInAnimationAdapter(undoAdapter);
animAdapter.setAbsListView(mListView);
mListView.setAdapter(animAdapter);
3. 粘性列表头支持
// 使用StickyListHeadersAdapterDecorator
StickyListHeadersAdapterDecorator headersAdapter =
new StickyListHeadersAdapterDecorator(baseAdapter);
// 添加动画效果
AnimationAdapter animAdapter = new AlphaInAnimationAdapter(headersAdapter);
animAdapter.setAbsListView(listView);
listView.setAdapter(animAdapter);
布局文件配置
1. 动态列表布局
<com.nhaarman.listviewanimations.itemmanipulation.DynamicListView
android:id="@+id/activity_dynamiclistview_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="8dp"
android:padding="8dp" />
2. 列表项布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="72dp"
android:background="@drawable/card_background">
<!-- 拖拽手柄 -->
<ImageView
android:id="@+id/list_row_draganddrop_touchview"
android:layout_width="48dp"
android:layout_height="match_parent"
android:src="@drawable/ic_drag_handle"
android:scaleType="center"
android:contentDescription="@string/drag_handle" />
<!-- 内容区域 -->
<TextView
android:id="@+id/list_row_draganddrop_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/list_row_draganddrop_touchview"
android:gravity="center_vertical"
android:padding="16dp"
android:textSize="16sp" />
</RelativeLayout>
3. 撤销布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="72dp"
android:orientation="horizontal"
android:background="#FF4444"
android:gravity="center">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/item_deleted"
android:textColor="@android:color/white"
android:gravity="center"
android:textSize="16sp" />
<Button
android:id="@+id/undo_row_undobutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/undo"
android:textColor="@android:color/white"
style="?android:attr/borderlessButtonStyle" />
</LinearLayout>
性能优化建议
1. 动画延迟设置
// 设置初始延迟,避免同时动画造成的性能问题
animAdapter.getViewAnimator().setInitialDelayMillis(100);
2. 内存管理
@Override
protected void onDestroy() {
super.onDestroy();
// 清理动画资源
if (animAdapter != null && animAdapter.getViewAnimator() != null) {
animAdapter.getViewAnimator().reset();
}
}
3. 状态保存与恢复
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (animAdapter != null) {
outState.putParcelable("animation_state", animAdapter.onSaveInstanceState());
}
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (animAdapter != null && savedInstanceState != null) {
animAdapter.onRestoreInstanceState(savedInstanceState.getParcelable("animation_state"));
}
}
常见问题解决
1. 动画不生效
- 确保调用了
setAbsListView()方法 - 检查适配器包装顺序是否正确
2. 拖拽功能异常
- 确认设置了正确的DraggableManager
- 检查触摸视图的ID配置
3. 滑动删除无响应
- 验证OnDismissCallback实现是否正确
- 检查列表项布局的触摸事件处理
4. 性能问题
- 减少同时进行的动画数量
- 适当增加动画延迟时间
- 避免在动画过程中进行复杂计算
最佳实践
- 适度使用动画:动画效果应该增强用户体验,而不是分散注意力
- 保持一致性:在整个应用中保持相似的动画风格和时长
- 性能优先:在低端设备上考虑减少或禁用复杂动画
- 用户可控:提供设置选项让用户选择是否启用动画效果
- 测试兼容性:在不同Android版本和设备上测试动画效果
迁移到RecyclerView
虽然ListViewAnimations仍然可用,但建议新项目使用RecyclerView + ItemAnimator的方案:
// RecyclerView的简单动画实现
RecyclerView.ItemAnimator animator = new DefaultItemAnimator();
animator.setAddDuration(300);
animator.setRemoveDuration(300);
animator.setMoveDuration(300);
recyclerView.setItemAnimator(animator);
ListViewAnimations作为一个成熟的Android动画库,为传统ListView提供了丰富的交互动画功能。尽管现在推荐使用RecyclerView,但对于需要维护旧代码库或特定场景下的开发,这个库仍然具有很高的实用价值。通过合理的配置和使用,可以显著提升应用的用户体验。
登录后查看全文
热门项目推荐
相关项目推荐
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust098- DDeepSeek-V4-ProDeepSeek-V4-Pro(总参数 1.6 万亿,激活 49B)面向复杂推理和高级编程任务,在代码竞赛、数学推理、Agent 工作流等场景表现优异,性能接近国际前沿闭源模型。Python00
MiMo-V2.5-ProMiMo-V2.5-Pro作为旗舰模型,擅⻓处理复杂Agent任务,单次任务可完成近千次⼯具调⽤与⼗余轮上 下⽂压缩。Python00
GLM-5.1GLM-5.1是智谱迄今最智能的旗舰模型,也是目前全球最强的开源模型。GLM-5.1大大提高了代码能力,在完成长程任务方面提升尤为显著。和此前分钟级交互的模型不同,它能够在一次任务中独立、持续工作超过8小时,期间自主规划、执行、自我进化,最终交付完整的工程级成果。Jinja00
Kimi-K2.6Kimi K2.6 是一款开源的原生多模态智能体模型,在长程编码、编码驱动设计、主动自主执行以及群体任务编排等实用能力方面实现了显著提升。Python00
MiniMax-M2.7MiniMax-M2.7 是我们首个深度参与自身进化过程的模型。M2.7 具备构建复杂智能体应用框架的能力,能够借助智能体团队、复杂技能以及动态工具搜索,完成高度精细的生产力任务。Python00
项目优选
收起
暂无描述
Dockerfile
703
4.51 K
Ascend Extension for PyTorch
Python
567
693
Claude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed.
Get Started
Rust
547
98
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
957
955
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
411
338
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
1.6 K
940
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
1.08 K
566
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
128
210
暂无简介
Dart
948
235
Oohos_react_native
React Native鸿蒙化仓库
C++
340
387