Java tutorial
/* * Copyright (c) 2015 GuDong * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.gudong.appkit.ui.helper; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.support.v4.animation.AnimatorCompatHelper; import android.support.v4.view.ViewCompat; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SimpleItemAnimator; import android.view.View; import android.view.animation.AccelerateInterpolator; import com.gudong.appkit.BuildConfig; import java.util.ArrayList; import java.util.List; /** * Created by GuDong on 12/9/15 17:07. * Contact with 1252768410@qq.com. */ // TODO remove anim has some problem and fix it public class AppItemAnimator extends SimpleItemAnimator { private static final int KEY_DURATION_TIME = 500; private ArrayList<RecyclerView.ViewHolder> mPendingAdditions = new ArrayList<>(); private ArrayList<ArrayList<RecyclerView.ViewHolder>> mAdditionsList = new ArrayList<>(); private List<RecyclerView.ViewHolder> mAddAnimations = new ArrayList<>(); @Override public boolean animateRemove(RecyclerView.ViewHolder holder) { return false; } @Override public boolean animateAdd(RecyclerView.ViewHolder holder) { resetAnimation(holder); ViewCompat.setAlpha(holder.itemView, 0); mPendingAdditions.add(holder); return true; } private void resetAnimation(RecyclerView.ViewHolder holder) { AnimatorCompatHelper.clearInterpolator(holder.itemView); endAnimation(holder); } @Override public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) { return false; } @Override public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop) { return false; } @Override public void runPendingAnimations() { boolean additionsPending = !mPendingAdditions.isEmpty(); if (!additionsPending) { // nothing to animate return; } if (additionsPending) { final ArrayList<RecyclerView.ViewHolder> additions = new ArrayList<>(); additions.addAll(mPendingAdditions); mAdditionsList.add(additions); mPendingAdditions.clear(); Runnable adder = new Runnable() { @Override public void run() { for (RecyclerView.ViewHolder holder : additions) { animateAddImpl(holder); } additions.clear(); mAdditionsList.remove(additions); } }; adder.run(); } } private void animateAddImpl(final RecyclerView.ViewHolder viewHolder) { final View target = viewHolder.itemView; mAddAnimations.add(viewHolder); final AnimatorSet animator = new AnimatorSet(); animator.playTogether(ObjectAnimator.ofFloat(target, "translationX", -target.getMeasuredWidth(), 0, 0f), ObjectAnimator.ofFloat(target, "alpha", 0.5f, 1.0f)); animator.setTarget(target); animator.setDuration(KEY_DURATION_TIME); animator.setInterpolator(new AccelerateInterpolator()); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); dispatchAddStarting(viewHolder); } @Override public void onAnimationCancel(Animator animation) { super.onAnimationCancel(animation); ViewCompat.setAlpha(target, 1); } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); animator.removeAllListeners(); dispatchAddFinished(viewHolder); mAddAnimations.remove(viewHolder); dispatchFinishedWhenDone(); } }); animator.start(); } /** * Check the state of currently pending and running animations. If there are none * pending/running, call {@link #dispatchAnimationsFinished()} to notify any * listeners. */ private void dispatchFinishedWhenDone() { if (!isRunning()) { dispatchAnimationsFinished(); } } @Override public void endAnimation(RecyclerView.ViewHolder item) { final View view = item.itemView; // this will trigger end callback which should set properties to their target values. ViewCompat.animate(view).cancel(); for (int i = mAdditionsList.size() - 1; i >= 0; i--) { ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i); if (additions.remove(item)) { ViewCompat.setAlpha(view, 1); dispatchAddFinished(item); if (additions.isEmpty()) { mAdditionsList.remove(i); } } } //noinspection PointlessBooleanExpression,ConstantConditions if (mAddAnimations.remove(item) && BuildConfig.DEBUG) { throw new IllegalStateException( "after animation is cancelled, item should not be in " + "mAddAnimations list"); } } @Override public void endAnimations() { int count = mPendingAdditions.size(); for (int i = count - 1; i >= 0; i--) { RecyclerView.ViewHolder item = mPendingAdditions.get(i); View view = item.itemView; ViewCompat.setAlpha(view, 1); dispatchAddFinished(item); mPendingAdditions.remove(i); } int listCount = mAdditionsList.size(); for (int i = listCount - 1; i >= 0; i--) { ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i); count = additions.size(); for (int j = count - 1; j >= 0; j--) { RecyclerView.ViewHolder item = additions.get(j); View view = item.itemView; ViewCompat.setAlpha(view, 1); dispatchAddFinished(item); additions.remove(j); if (additions.isEmpty()) { mAdditionsList.remove(additions); } } } cancelAll(mAddAnimations); dispatchAnimationsFinished(); } void cancelAll(List<RecyclerView.ViewHolder> viewHolders) { for (int i = viewHolders.size() - 1; i >= 0; i--) { ViewCompat.animate(viewHolders.get(i).itemView).cancel(); } } @Override public boolean isRunning() { return !(mAddAnimations.isEmpty()); } }