Android Open Source - ListViewAnimations View Animator






From Project

Back to project page ListViewAnimations.

License

The source code is released under:

Apache License

If you think the Android project ListViewAnimations listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2014 Niek Haarman/*from  w  w w  .j a v a 2s .c  om*/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.nhaarman.listviewanimations.appearance;

import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.SparseArray;
import android.view.View;
import android.widget.GridView;

import com.nhaarman.listviewanimations.util.ListViewWrapper;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.view.ViewHelper;

/**
 * A class which decides whether given Views should be animated based on their position: each View should only be animated once.
 * It also calculates proper animation delays for the views.
 */
public class ViewAnimator {

    /* Saved instance state keys */
    private static final String SAVEDINSTANCESTATE_FIRSTANIMATEDPOSITION = "savedinstancestate_firstanimatedposition";
    private static final String SAVEDINSTANCESTATE_LASTANIMATEDPOSITION = "savedinstancestate_lastanimatedposition";
    private static final String SAVEDINSTANCESTATE_SHOULDANIMATE = "savedinstancestate_shouldanimate";

    /* Default values */

    /**
     * The default delay in millis before the first animation starts.
     */
    private static final int INITIAL_DELAY_MILLIS = 150;

    /**
     * The default delay in millis between view animations.
     */
    private static final int DEFAULT_ANIMATION_DELAY_MILLIS = 100;

    /**
     * The default duration in millis of the animations.
     */
    private static final int DEFAULT_ANIMATION_DURATION_MILLIS = 300;

    /* Fields */

    /**
     * The ListViewWrapper containing the ListView implementation.
     */
    @NonNull
    private final ListViewWrapper mListViewWrapper;

    /**
     * The active Animators. Keys are hashcodes of the Views that are animated.
     */
    @NonNull
    private final SparseArray<Animator> mAnimators = new SparseArray<>();

    /**
     * The delay in millis before the first animation starts.
     */
    private int mInitialDelayMillis = INITIAL_DELAY_MILLIS;

    /**
     * The delay in millis between view animations.
     */
    private int mAnimationDelayMillis = DEFAULT_ANIMATION_DELAY_MILLIS;

    /**
     * The duration in millis of the animations.
     */
    private int mAnimationDurationMillis = DEFAULT_ANIMATION_DURATION_MILLIS;

    /**
     * The start timestamp of the first animation, as returned by {@link android.os.SystemClock#uptimeMillis()}.
     */
    private long mAnimationStartMillis;

    /**
     * The position of the item that is the first that was animated.
     */
    private int mFirstAnimatedPosition;

    /**
     * The position of the last item that was animated.
     */
    private int mLastAnimatedPosition;

    /**
     * Whether animation is enabled. When this is set to false, no animation is applied to the views.
     */
    private boolean mShouldAnimate = true;

    /**
     * Creates a new ViewAnimator, using the given {@link com.nhaarman.listviewanimations.util.ListViewWrapper}.
     *
     * @param listViewWrapper the {@code ListViewWrapper} which wraps the implementation of the ListView used.
     */
    public ViewAnimator(@NonNull final ListViewWrapper listViewWrapper) {
        mListViewWrapper = listViewWrapper;
        mAnimationStartMillis = -1;
        mFirstAnimatedPosition = -1;
        mLastAnimatedPosition = -1;
    }

    /**
     * Call this method to reset animation status on all views.
     */
    public void reset() {
        for (int i = 0; i < mAnimators.size(); i++) {
            mAnimators.get(mAnimators.keyAt(i)).cancel();
        }
        mAnimators.clear();
        mFirstAnimatedPosition = -1;
        mLastAnimatedPosition = -1;
        mAnimationStartMillis = -1;
        mShouldAnimate = true;
    }

    /**
     * Set the starting position for which items should animate. Given position will animate as well.
     * Will also call {@link #enableAnimations()}.
     *
     * @param position the position.
     */
    public void setShouldAnimateFromPosition(final int position) {
        enableAnimations();
        mFirstAnimatedPosition = position - 1;
        mLastAnimatedPosition = position - 1;
    }

    /**
     * Set the starting position for which items should animate as the first position which isn't currently visible on screen. This call is also valid when the {@link View}s
     * haven't been drawn yet. Will also call {@link #enableAnimations()}.
     */
    public void setShouldAnimateNotVisible() {
        enableAnimations();
        mFirstAnimatedPosition = mListViewWrapper.getLastVisiblePosition();
        mLastAnimatedPosition = mListViewWrapper.getLastVisiblePosition();
    }

    /**
     * Sets the value of the last animated position. Views with positions smaller than or equal to given value will not be animated.
     */
    void setLastAnimatedPosition(final int lastAnimatedPosition) {
        mLastAnimatedPosition = lastAnimatedPosition;
    }

    /**
     * Sets the delay in milliseconds before the first animation should start. Defaults to {@value #INITIAL_DELAY_MILLIS}.
     *
     * @param delayMillis the time in milliseconds.
     */
    public void setInitialDelayMillis(final int delayMillis) {
        mInitialDelayMillis = delayMillis;
    }

    /**
     * Sets the delay in milliseconds before an animation of a view should start. Defaults to {@value #DEFAULT_ANIMATION_DELAY_MILLIS}.
     *
     * @param delayMillis the time in milliseconds.
     */
    public void setAnimationDelayMillis(final int delayMillis) {
        mAnimationDelayMillis = delayMillis;
    }

    /**
     * Sets the duration of the animation in milliseconds. Defaults to {@value #DEFAULT_ANIMATION_DURATION_MILLIS}.
     *
     * @param durationMillis the time in milliseconds.
     */
    public void setAnimationDurationMillis(final int durationMillis) {
        mAnimationDurationMillis = durationMillis;
    }

    /**
     * Enables animating the Views. This is the default.
     */
    public void enableAnimations() {
        mShouldAnimate = true;
    }

    /**
     * Disables animating the Views. Enable them again using {@link #enableAnimations()}.
     */
    public void disableAnimations() {
        mShouldAnimate = false;
    }

    /**
     * Cancels any existing animations for given View.
     */
    void cancelExistingAnimation(@NonNull final View view) {
        int hashCode = view.hashCode();
        Animator animator = mAnimators.get(hashCode);
        if (animator != null) {
            animator.end();
            mAnimators.remove(hashCode);
        }
    }

    /**
     * Animates given View if necessary.
     *
     * @param position the position of the item the View represents.
     * @param view     the View that should be animated.
     */
    public void animateViewIfNecessary(final int position, @NonNull final View view, @NonNull final Animator[] animators) {
        if (mShouldAnimate && position > mLastAnimatedPosition) {
            if (mFirstAnimatedPosition == -1) {
                mFirstAnimatedPosition = position;
            }

            animateView(position, view, animators);
            mLastAnimatedPosition = position;
        }
    }

    /**
     * Animates given View.
     *
     * @param view the View that should be animated.
     */
    private void animateView(final int position, @NonNull final View view, @NonNull final Animator[] animators) {
        if (mAnimationStartMillis == -1) {
            mAnimationStartMillis = SystemClock.uptimeMillis();
        }

        ViewHelper.setAlpha(view, 0);

        AnimatorSet set = new AnimatorSet();
        set.playTogether(animators);
        set.setStartDelay(calculateAnimationDelay(position));
        set.setDuration(mAnimationDurationMillis);
        set.start();

        mAnimators.put(view.hashCode(), set);
    }

    /**
     * Returns the delay in milliseconds after which animation for View with position mLastAnimatedPosition + 1 should start.
     */
    @SuppressLint("NewApi")
    private int calculateAnimationDelay(final int position) {
        int delay;

        int lastVisiblePosition = mListViewWrapper.getLastVisiblePosition();
        int firstVisiblePosition = mListViewWrapper.getFirstVisiblePosition();

        int numberOfItemsOnScreen = lastVisiblePosition - firstVisiblePosition;
        int numberOfAnimatedItems = position - 1 - mFirstAnimatedPosition;

        if (numberOfItemsOnScreen + 1 < numberOfAnimatedItems) {
            delay = mAnimationDelayMillis;

            if (mListViewWrapper.getListView() instanceof GridView && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                int numColumns = ((GridView) mListViewWrapper.getListView()).getNumColumns();
                delay += mAnimationDelayMillis * (position % numColumns);
            }
        } else {
            int delaySinceStart = (position - mFirstAnimatedPosition) * mAnimationDelayMillis;
            delay = Math.max(0, (int) (-SystemClock.uptimeMillis() + mAnimationStartMillis + mInitialDelayMillis + delaySinceStart));
        }
        return delay;
    }

    /**
     * Returns a Parcelable object containing the AnimationAdapter's current dynamic state.
     */
    @NonNull
    public Parcelable onSaveInstanceState() {
        Bundle bundle = new Bundle();

        bundle.putInt(SAVEDINSTANCESTATE_FIRSTANIMATEDPOSITION, mFirstAnimatedPosition);
        bundle.putInt(SAVEDINSTANCESTATE_LASTANIMATEDPOSITION, mLastAnimatedPosition);
        bundle.putBoolean(SAVEDINSTANCESTATE_SHOULDANIMATE, mShouldAnimate);

        return bundle;
    }

    /**
     * Restores this AnimationAdapter's state.
     *
     * @param parcelable the Parcelable object previously returned by {@link #onSaveInstanceState()}.
     */
    public void onRestoreInstanceState(@Nullable final Parcelable parcelable) {
        if (parcelable instanceof Bundle) {
            Bundle bundle = (Bundle) parcelable;
            mFirstAnimatedPosition = bundle.getInt(SAVEDINSTANCESTATE_FIRSTANIMATEDPOSITION);
            mLastAnimatedPosition = bundle.getInt(SAVEDINSTANCESTATE_LASTANIMATEDPOSITION);
            mShouldAnimate = bundle.getBoolean(SAVEDINSTANCESTATE_SHOULDANIMATE);
        }
    }
}




Java Source Code List

com.haarman.listviewanimations.BaseActivity.java
com.haarman.listviewanimations.MainActivity.java
com.haarman.listviewanimations.MyListActivity.java
com.haarman.listviewanimations.MyListAdapter.java
com.haarman.listviewanimations.StickyListHeadersActivity.java
com.haarman.listviewanimations.appearance.AppearanceExamplesActivity.java
com.haarman.listviewanimations.googlecards.GoogleCardsActivity.java
com.haarman.listviewanimations.googlecards.GoogleCardsAdapter.java
com.haarman.listviewanimations.gridview.GridViewActivity.java
com.haarman.listviewanimations.gridview.GridViewAdapter.java
com.haarman.listviewanimations.itemmanipulation.DynamicListViewActivity.java
com.haarman.listviewanimations.itemmanipulation.ItemManipulationsExamplesActivity.java
com.haarman.listviewanimations.itemmanipulation.expandablelistitems.ExpandableListItemActivity.java
com.haarman.listviewanimations.itemmanipulation.expandablelistitems.MyExpandableListItemAdapter.java
com.haarman.listviewanimations.util.BitmapCache.java
com.nhaarman.listviewanimations.ArrayAdapterTest.java
com.nhaarman.listviewanimations.ArrayAdapter.java
com.nhaarman.listviewanimations.BaseAdapterDecoratorTest.java
com.nhaarman.listviewanimations.BaseAdapterDecorator.java
com.nhaarman.listviewanimations.appearance.AnimationAdapter.java
com.nhaarman.listviewanimations.appearance.ResourceAnimationAdapter.java
com.nhaarman.listviewanimations.appearance.SingleAnimationAdapter.java
com.nhaarman.listviewanimations.appearance.StickyListHeadersAdapterDecorator.java
com.nhaarman.listviewanimations.appearance.ViewAnimatorTest.java
com.nhaarman.listviewanimations.appearance.ViewAnimator.java
com.nhaarman.listviewanimations.appearance.simple.AlphaInAnimationAdapter.java
com.nhaarman.listviewanimations.appearance.simple.ScaleInAnimationAdapter.java
com.nhaarman.listviewanimations.appearance.simple.SwingBottomInAnimationAdapter.java
com.nhaarman.listviewanimations.appearance.simple.SwingLeftInAnimationAdapter.java
com.nhaarman.listviewanimations.appearance.simple.SwingRightInAnimationAdapter.java
com.nhaarman.listviewanimations.itemmanipulation.DynamicListView.java
com.nhaarman.listviewanimations.itemmanipulation.TouchEventHandler.java
com.nhaarman.listviewanimations.itemmanipulation.animateaddition.AnimateAdditionAdapter.java
com.nhaarman.listviewanimations.itemmanipulation.animateaddition.InsertQueueTest.java
com.nhaarman.listviewanimations.itemmanipulation.animateaddition.InsertQueue.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.BitmapUtils.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.DragAndDropHandler.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.DragAndDropListViewWrapper.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.DraggableManager.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.DynamicListViewDragAndDropTest.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.DynamicListViewTestActivity.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.DynamicListViewWrapper.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.GripView.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.HoverDrawableTest.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.HoverDrawable.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.MotionEventUtils.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.OnItemMovedListener.java
com.nhaarman.listviewanimations.itemmanipulation.dragdrop.TouchViewDraggableManager.java
com.nhaarman.listviewanimations.itemmanipulation.expandablelistitem.ExpandableListItemAdapter.java
com.nhaarman.listviewanimations.itemmanipulation.matchers.Matchers.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.DismissableManager.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.MotionEventUtils.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.OnDismissCallback.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeDismissAdapter.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeDismissTouchListenerTest.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeDismissTouchListener.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeTouchListenerTestActivity.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeTouchListenerTest.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.SwipeTouchListener.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.SimpleSwipeUndoAdapter.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.SwipeUndoAdapter.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.SwipeUndoTouchListenerTest.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.SwipeUndoTouchListener.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.SwipeUndoView.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.TimedUndoAdapter.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.UndoAdapter.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.UndoCallback.java
com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.Util.java
com.nhaarman.listviewanimations.util.AbsListViewWrapperTest.java
com.nhaarman.listviewanimations.util.AbsListViewWrapper.java
com.nhaarman.listviewanimations.util.AdapterViewUtilTest.java
com.nhaarman.listviewanimations.util.AdapterViewUtil.java
com.nhaarman.listviewanimations.util.AnimatorUtilTest.java
com.nhaarman.listviewanimations.util.AnimatorUtil.java
com.nhaarman.listviewanimations.util.Insertable.java
com.nhaarman.listviewanimations.util.ListViewWrapperSetter.java
com.nhaarman.listviewanimations.util.ListViewWrapper.java
com.nhaarman.listviewanimations.util.StickyListHeadersListViewWrapper.java
com.nhaarman.listviewanimations.util.Swappable.java