这篇博客带来一个支持item交换动画的ListView。话不多说,先上效果。
实现的效果就是,通过手动操作交换ListView中两个item的位置,并在交换时附带移动交换效果。之前在知乎的app上看到过这种效果,顺手写了一个,搬运上来跟大家分享一下。
核心组件就一个 TranslationListView.java :
public class TranslationListView extends ListView {
/**
* 速度模板,影响视图移动时的速度变化
*
* MODE_LINEAR // 线性变化模式
* MODE_ACCELERATE // 加速模式
* MODE_DECELERATE // 减速模式
* MODE_ACCELERATE_DECELERATE // 先加速后加速模式
*
*/
public static final int MODE_LINEAR = 0x001;
public static final int MODE_ACCELERATE = 0x002;
public static final int MODE_DECELERATE = 0x003;
public static final int MODE_ACCELERATE_DECELERATE = 0x004;
/**
* 可设置选项
*/
// 移动动画储持续时间,单位毫秒
private long duration = 300;
// 速度模板
private int speedMode = MODE_ACCELERATE_DECELERATE;
// 移动监听接口
private OnTranslateListener translateListener;
// 移动锁定标识
private boolean isLock;
public TranslationListView(Context context) {
super(context);
}
public TranslationListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TranslationListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 将指定项上移一格
*
* @param position 指定项的序坐标
*/
public void moveUp(int position) {
translate(position, position - 1);
}
/**
* 将指定项下移一格
*
* @param position 指定项的坐标
*/
public void moveDown(int position) {
translate(position, position + 1);
}
/**
* 执行移动方法
*
* @param fromPosition // 起始坐标
* @param toPosition // 终点坐标
*/
private void translate(final int fromPosition, final int toPosition) {
if (isLock) {
return;
}
View fromView = getChildAt(fromPosition - getFirstVisiblePosition());
View toView = getChildAt(toPosition - getFirstVisiblePosition());
if (fromView == null || toView == null) {
return;
}
float distance = toView.getY() - fromView.getY();
ObjectAnimator fromAnimator = ObjectAnimator.ofFloat(fromView, "translationY", 0, distance);
ObjectAnimator toAnimator = ObjectAnimator.ofFloat(toView, "translationY", 0, -distance);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(Arrays.as