public void remove(int position){
list.remove(position);
notifyItemRemoved(position);
}
public void add(int position,String data) {
list.add(position,data);
notifyItemInserted(position);
}
public void change(int position,String data) {
list.remove(position);
list.add(position,data);
notifyItemChanged(position);
}
可以發現他和ListView的刷新不同的是,對應不同的刪除添加或者改變對應的notify都是不同的,如果不這樣的話那麼添加刪除改變的動畫將沒有。 case R.id.btn_add:
myAdapter.add(0,"新加數據");
myRecyclerView.scrollToPosition(0);
break;
case R.id.btn_delete:
myAdapter.remove(0);
break;
case R.id.btn_change:
myAdapter.change(0,"改變的數據");
break;
注意!!!可以發現增加的時候多了一個方法,那麼這個方法是定位顯示的條目位置的,當你新添加方法的時候他不會顯示出來,需要將條目位置進行設定。//設置默認動畫
DefaultItemAnimator animator = new DefaultItemAnimator();
//設置動畫時間
animator.setAddDuration(2000);
animator.setRemoveDuration(2000);
myRecyclerView.setItemAnimator(animator);
@Override
public boolean animateRemove(final ViewHolder holder) {
resetAnimation(holder);
mPendingRemovals.add(holder);
return true;
}
這段代碼是將移除動畫添加到集合當中private void animateRemoveImpl(final ViewHolder holder) {
final View view = holder.itemView;//首先得到ItemView
final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);//開啓一個屬性動畫
mRemoveAnimations.add(holder);//加入到要刪除的VIew中
/* animation.setDuration(getRemoveDuration())//設置延遲時間
.alpha(0).setListener(new VpaListenerAdapter() {//listener是開始和結束的監聽*/
animation.setDuration(getRemoveDuration())//設置延遲時間
.translationX(view.getWidth()).setListener(new VpaListenerAdapter() {//listener是開始和結束的監聽
//變到哪裏
@Override
public void onAnimationStart(View view) {
dispatchRemoveStarting(holder);
}
@Override
public void onAnimationEnd(View view) {
animation.setListener(null);//當動畫結束的時候要將監聽置爲空
//ViewCompat.setAlpha(view, 1);//因爲有複用佈局的問題,所以你將控件刪除的時候需要將他還原,要不會出現重複問題
ViewCompat.setTranslationX(view, 0);//因爲有複用佈局的問題,所以你將控件刪除的時候需要將他還原,要不會出現重複問題
dispatchRemoveFinished(holder);
mRemoveAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
private void animateRemoveImpl(final ViewHolder holder) {
final View view = holder.itemView;//首先得到ItemView
final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);//開啓一個屬性動畫
mRemoveAnimations.add(holder);//加入到要刪除的VIew中
animation.setDuration(getRemoveDuration())//設置延遲時間
.translationX(view.getWidth()).setListener(new VpaListenerAdapter() {//listener是開始和結束的監聽
@Override
public void onAnimationStart(View view) {
dispatchRemoveStarting(holder);
}
@Override
public void onAnimationEnd(View view) {
animation.setListener(null);//當動畫結束的時候要將監聽置爲空
//ViewCompat.setAlpha(view, 1);//因爲有複用佈局的問題,所以你將控件刪除的時候需要將他還原,要不會出現重複問題
ViewCompat.setTranslationX(view,0);//因爲有複用佈局的問題,所以你將控件刪除的時候需要將他還原,要不會出現重複問題
dispatchRemoveFinished(holder);
mRemoveAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
myItemAnimator = new MyItemAnimator();
myItemAnimator.setRemoveDuration(2000);
myRecyclerVIew.setItemAnimator(myItemAnimator);
@Override
public boolean animateAdd(final ViewHolder holder) {
resetAnimation(holder);
ViewCompat.setAlpha(holder.itemView, 0);
mPendingAdditions.add(holder);
return true;
}
void animateAddImpl(final ViewHolder holder) {
final View view = holder.itemView;
final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);
mAddAnimations.add(holder);
animation.alpha(1).setDuration(getAddDuration()).
setListener(new VpaListenerAdapter() {
@Override
public void onAnimationStart(View view) {
dispatchAddStarting(holder);
}
@Override
public void onAnimationCancel(View view) {
ViewCompat.setAlpha(view, 1);
}
@Override
public void onAnimationEnd(View view) {
animation.setListener(null);
dispatchAddFinished(holder);
mAddAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
@Override
public boolean animateAdd(final ViewHolder holder) {
resetAnimation(holder);
//ViewCompat.setAlpha(holder.itemView, 0);
ViewCompat.setTranslationX(holder.itemView,-holder.itemView.getWidth());
mPendingAdditions.add(holder);
return true;
}
void animateAddImpl(final ViewHolder holder) {
final View view = holder.itemView;
final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);
mAddAnimations.add(holder);
//animation.alpha(1).setDuration(getAddDuration()).
animation.translationX(0).setDuration(getAddDuration()).
setListener(new VpaListenerAdapter() {
@Override
public void onAnimationStart(View view) {
dispatchAddStarting(holder);
}
@Override
public void onAnimationCancel(View view) {
ViewCompat.setAlpha(view, 1);
}
@Override
public void onAnimationEnd(View view) {
animation.setListener(null);
dispatchAddFinished(holder);
mAddAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
myItemAnimator = new MyItemAnimator();
myItemAnimator.setAddDuration(2000);
myRecyclerVIew.setItemAnimator(myItemAnimator);
@Override
public boolean animateMove(final ViewHolder holder, int fromX, int fromY,
int toX, int toY) {
final View view = holder.itemView;
fromX += ViewCompat.getTranslationX(holder.itemView);
fromY += ViewCompat.getTranslationY(holder.itemView);
resetAnimation(holder);
int deltaX = toX - fromX;
int deltaY = toY - fromY;
if (deltaX == 0 && deltaY == 0) {
dispatchMoveFinished(holder);
return false;
}
if (deltaX != 0) {
ViewCompat.setTranslationX(view, -deltaX);
}
if (deltaY != 0) {
ViewCompat.setTranslationY(view, -deltaY);
}
mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
return true;
}
void animateMoveImpl(final ViewHolder holder, int fromX, int fromY, int toX, int toY) {
final View view = holder.itemView;
final int deltaX = toX - fromX;
final int deltaY = toY - fromY;
if (deltaX != 0) {
ViewCompat.animate(view).translationX(0);
}
if (deltaY != 0) {
ViewCompat.animate(view).translationY(0);
}
// TODO: make EndActions end listeners instead, since end actions aren't called when
// vpas are canceled (and can't end them. why?)
// need listener functionality in VPACompat for this. Ick.
final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);
mMoveAnimations.add(holder);
animation.setDuration(getMoveDuration()).setListener(new VpaListenerAdapter() {
@Override
public void onAnimationStart(View view) {
dispatchMoveStarting(holder);
}
@Override
public void onAnimationCancel(View view) {
if (deltaX != 0) {
ViewCompat.setTranslationX(view, 0);
}
if (deltaY != 0) {
ViewCompat.setTranslationY(view, 0);
}
}
@Override
public void onAnimationEnd(View view) {
animation.setListener(null);
dispatchMoveFinished(holder);
mMoveAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
在animateMoveImpl中添加我們的翻轉動畫
animation.rotationXBy(180);
因爲我們是翻轉180度那麼需要在後面進行重置ViewCompat.setRotationX(view,0);
更改後的所有代碼
void animateMoveImpl(final ViewHolder holder, int fromX, int fromY, int toX, int toY) {
final View view = holder.itemView;
final int deltaX = toX - fromX;
final int deltaY = toY - fromY;
if (deltaX != 0) {
ViewCompat.animate(view).translationX(0);
}
if (deltaY != 0) {
ViewCompat.animate(view).translationY(0);
}
// TODO: make EndActions end listeners instead, since end actions aren't called when
// vpas are canceled (and can't end them. why?)
// need listener functionality in VPACompat for this. Ick.
final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);
animation.rotationXBy(180);
mMoveAnimations.add(holder);
animation.setDuration(getMoveDuration()).setListener(new VpaListenerAdapter() {
@Override
public void onAnimationStart(View view) {
dispatchMoveStarting(holder);
}
@Override
public void onAnimationCancel(View view) {
if (deltaX != 0) {
ViewCompat.setTranslationX(view, 0);
}
if (deltaY != 0) {
ViewCompat.setTranslationY(view, 0);
}
}
@Override
public void onAnimationEnd(View view) {
animation.setListener(null);
ViewCompat.setRotationX(view,0);
dispatchMoveFinished(holder);
mMoveAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
@Override
public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder,
int fromX, int fromY, int toX, int toY) {
if (oldHolder == newHolder) {
// Don't know how to run change animations when the same view holder is re-used.
// run a move animation to handle position changes.
return animateMove(oldHolder, fromX, fromY, toX, toY);
}
final float prevTranslationX = ViewCompat.getTranslationX(oldHolder.itemView);
final float prevTranslationY = ViewCompat.getTranslationY(oldHolder.itemView);
final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView);
resetAnimation(oldHolder);
int deltaX = (int) (toX - fromX - prevTranslationX);
int deltaY = (int) (toY - fromY - prevTranslationY);
// recover prev translation state after ending animation
ViewCompat.setTranslationX(oldHolder.itemView, prevTranslationX);
ViewCompat.setTranslationY(oldHolder.itemView, prevTranslationY);
ViewCompat.setAlpha(oldHolder.itemView, prevAlpha);
if (newHolder != null) {
// carry over translation values
resetAnimation(newHolder);
ViewCompat.setTranslationX(newHolder.itemView, -deltaX);
ViewCompat.setTranslationY(newHolder.itemView, -deltaY);
ViewCompat.setAlpha(newHolder.itemView, 0);
}
mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY));
return true;
}
void animateChangeImpl(final ChangeInfo changeInfo) {
final ViewHolder holder = changeInfo.oldHolder;
final View view = holder == null ? null : holder.itemView;
final ViewHolder newHolder = changeInfo.newHolder;
final View newView = newHolder != null ? newHolder.itemView : null;
if (view != null) {
final ViewPropertyAnimatorCompat oldViewAnim = ViewCompat.animate(view).setDuration(
getChangeDuration());
mChangeAnimations.add(changeInfo.oldHolder);
oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX);
oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY);
oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() {
@Override
public void onAnimationStart(View view) {
dispatchChangeStarting(changeInfo.oldHolder, true);
}
@Override
public void onAnimationEnd(View view) {
oldViewAnim.setListener(null);
ViewCompat.setAlpha(view, 1);
ViewCompat.setTranslationX(view, 0);
ViewCompat.setTranslationY(view, 0);
dispatchChangeFinished(changeInfo.oldHolder, true);
mChangeAnimations.remove(changeInfo.oldHolder);
dispatchFinishedWhenDone();
}
}).start();
}
@Override
public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder,
int fromX, int fromY, int toX, int toY) {
if (oldHolder == newHolder) {
// Don't know how to run change animations when the same view holder is re-used.
// run a move animation to handle position changes.
return animateMove(oldHolder, fromX, fromY, toX, toY);
}
final float prevTranslationX = ViewCompat.getTranslationX(oldHolder.itemView);
final float prevTranslationY = ViewCompat.getTranslationY(oldHolder.itemView);
final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView);
resetAnimation(oldHolder);
int deltaX = (int) (toX - fromX - prevTranslationX);
int deltaY = (int) (toY - fromY - prevTranslationY);
// recover prev translation state after ending animation
ViewCompat.setTranslationX(oldHolder.itemView, prevTranslationX);
ViewCompat.setTranslationY(oldHolder.itemView, prevTranslationY);
ViewCompat.setAlpha(oldHolder.itemView, prevAlpha);
if (newHolder != null) {
// carry over translation values
resetAnimation(newHolder);
ViewCompat.setTranslationX(newHolder.itemView, -deltaX);
ViewCompat.setTranslationY(newHolder.itemView, -deltaY);
//ViewCompat.setAlpha(newHolder.itemView, 0);
//新的移除視線
ViewCompat.setTranslationX(newHolder.itemView,-newHolder.itemView.getWidth());
}
mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY));
return true;
}
void animateChangeImpl(final ChangeInfo changeInfo) {
final ViewHolder holder = changeInfo.oldHolder;
final View view = holder == null ? null : holder.itemView;
final ViewHolder newHolder = changeInfo.newHolder;
final View newView = newHolder != null ? newHolder.itemView : null;
if (view != null) {
final ViewPropertyAnimatorCompat oldViewAnim = ViewCompat.animate(view).setDuration(
getChangeDuration());
mChangeAnimations.add(changeInfo.oldHolder);
oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX);
oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY);
//oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() {
//老的移除
oldViewAnim.translationX(view.getWidth()).setListener(new VpaListenerAdapter() {
@Override
public void onAnimationStart(View view) {
dispatchChangeStarting(changeInfo.oldHolder, true);
}
@Override
public void onAnimationEnd(View view) {
oldViewAnim.setListener(null);
ViewCompat.setAlpha(view, 1);
ViewCompat.setTranslationX(view, 0);
ViewCompat.setTranslationY(view, 0);
dispatchChangeFinished(changeInfo.oldHolder, true);
mChangeAnimations.remove(changeInfo.oldHolder);
dispatchFinishedWhenDone();
}
}).start();
}
if (newView != null) {
final ViewPropertyAnimatorCompat newViewAnimation = ViewCompat.animate(newView);
mChangeAnimations.add(changeInfo.newHolder);
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).
alpha(1).setListener(new VpaListenerAdapter() {
@Override
public void onAnimationStart(View view) {
dispatchChangeStarting(changeInfo.newHolder, false);
}
@Override
public void onAnimationEnd(View view) {
newViewAnimation.setListener(null);
ViewCompat.setAlpha(newView, 1);
ViewCompat.setTranslationX(newView, 0);
ViewCompat.setTranslationY(newView, 0);
dispatchChangeFinished(changeInfo.newHolder, false);
mChangeAnimations.remove(changeInfo.newHolder);
dispatchFinishedWhenDone();
}
}).start();
}
}