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,但对于需要维护旧代码库或特定场景下的开发,这个库仍然具有很高的实用价值。通过合理的配置和使用,可以显著提升应用的用户体验。
登录后查看全文
热门项目推荐
相关项目推荐
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00
GLM-4.7-FlashGLM-4.7-Flash 是一款 30B-A3B MoE 模型。作为 30B 级别中的佼佼者,GLM-4.7-Flash 为追求性能与效率平衡的轻量化部署提供了全新选择。Jinja00
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin07
compass-metrics-modelMetrics model project for the OSS CompassPython00
项目优选
收起
deepin linux kernel
C
27
11
OpenHarmony documentation | OpenHarmony开发者文档
Dockerfile
522
3.71 K
Ascend Extension for PyTorch
Python
327
384
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
875
576
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
334
161
暂无简介
Dart
762
184
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
1.32 K
744
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
12
1
React Native鸿蒙化仓库
JavaScript
302
349
华为昇腾面向大规模分布式训练的多模态大模型套件,支撑多模态生成、多模态理解。
Python
112
134