我正在尝试在RecyclerView
行中创建一个动画,其中Helper
类扩展为ItemTouchHelper.Callback
。
默认"滑动"使用ItemTouchHelper
的行为是,如果以足够的速度滑动一行,它将从视图中消失(即,滑动到dimiss)。就我而言,我想创建一个动画,如果发生这样的事件,会导致行直接反弹。
我已经能够创建一个ValueAnimator
,如果它在屏幕上滑动,会将该行设置为动画。但是,问题是我无法让父ItemTouchHelper
类认识到它存储的x
值已从行的宽度(因此它完全在屏幕外)更改为{{1 (以便它回到屏幕上)。
这意味着每当我在完成自定义动画后与该行进行交互时,即使该行完全可见,它的行为就好像该行仍在屏幕外。这通常意味着按下它意味着行从0
的{{1}}位置跳到行宽的X
位置,因此从屏幕再次激活回来边缘。在完全重置并再次正常运行之前,它会执行此操作几次。
此视频有助于显示问题。由于前两次滑动不在屏幕外,因此默认行为有效。然后将行从屏幕上滑下并反弹回来,点击该行显示它从右边缘向后ping:
以下是我用来进行动画的代码:
0
请注意,此内部类X
是从public class CustomItemTouchHelper extends ItemTouchHelper.Callback {
private RecoverAnimation ra;
private boolean animatorRunning;
//...
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
final float per = (dX/viewHolder.itemView.getWidth());
if (per > 0.8F && !animatorRunning && !isCurrentlyActive) {
ra = new RecoverAnimation(c, recyclerView, viewHolder, ItemTouchHelper.ANIMATION_TYPE_SWIPE_CANCEL, actionState, dX, dY, 0, 0);
ra.start();
} else {
getDefaultUIUtil().onDraw(c, recyclerView, viewHolder.itemView, dX, dY, actionState, isCurrentlyActive);
}
}
//...
源代码中提取的:
RecoverAnimation
我有什么办法可以解决这个问题,或者它是否根本不可能?(
答案 0 :(得分:6)
以下解决方案将在不实施自定义RecoverAnimation类的情况下退回recyclelerview项目。
public class CustomItemTouchHelper extends ItemTouchHelper.Callback {
private RecoverAnimation ra;
private boolean animatorRunning;
private boolean swipeBack = false;
//...
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL)
{
swipeBack = true;
}
else
{
swipeBack = false;
}
return false;
}
});
}
@Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
return swipeBack ? 0 : super.convertToAbsoluteDirection(flags, layoutDirection);
}
//...