/* * Copyright 2013 Niek Haarman * * 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.haarman.listviewanimations.itemmanipulation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import junit.framework.Assert; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import com.haarman.listviewanimations.BaseAdapterDecorator; import com.nineoldandroids.animation.Animator; import com.nineoldandroids.animation.Animator.AnimatorListener; import com.nineoldandroids.animation.AnimatorSet; import com.nineoldandroids.animation.ValueAnimator; import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener; /** * A BaseAdapterDecorator class that provides animations to the removal of items * in the given BaseAdapter. */ public class AnimateDismissAdapter<T> extends BaseAdapterDecorator { private OnDismissCallback mCallback; /** * Create a new AnimateDismissAdapter based on the given ArrayAdapter. * * @param callback * The callback to trigger when the user has indicated that she * would like to dismiss one or more list items. */ public AnimateDismissAdapter(BaseAdapter baseAdapter, OnDismissCallback callback) { super(baseAdapter); mCallback = callback; } public void animateDismiss(int index) { animateDismiss(Arrays.asList(index)); } public void animateDismiss(Collection<Integer> positions) { final List<Integer> positionsCopy = new ArrayList<Integer>(positions); Assert.assertNotNull("Call setListView() on this AnimateDismissAdapter before calling setAdapter()!", getListView()); List<View> views = getVisibleViewsForPositions(positionsCopy); if (!views.isEmpty()) { List<Animator> animators = new ArrayList<Animator>(); for (final View view : views) { animators.add(createAnimatorForView(view)); } AnimatorSet animatorSet = new AnimatorSet(); Animator[] animatorsArray = new Animator[animators.size()]; for (int i = 0; i < animatorsArray.length; i++) { animatorsArray[i] = animators.get(i); } animatorSet.playTogether(animatorsArray); animatorSet.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator arg0) { } @Override public void onAnimationRepeat(Animator arg0) { } @Override public void onAnimationEnd(Animator arg0) { invokeCallback(positionsCopy); } @Override public void onAnimationCancel(Animator arg0) { } }); animatorSet.start(); } else { invokeCallback(positionsCopy); } } private void invokeCallback(Collection<Integer> positions) { ArrayList<Integer> positionsList = new ArrayList<Integer>(positions); Collections.sort(positionsList); int[] dismissPositions = new int[positionsList.size()]; for (int i = 0; i < positionsList.size(); i++) { dismissPositions[i] = positionsList.get(positionsList.size() - 1 - i); } mCallback.onDismiss(getListView(), dismissPositions); } private List<View> getVisibleViewsForPositions(Collection<Integer> positions) { List<View> views = new ArrayList<View>(); for (int i = 0; i < getListView().getChildCount(); i++) { View child = getListView().getChildAt(i); if (positions.contains(getListView().getPositionForView(child))) { views.add(child); } } return views; } private Animator createAnimatorForView(final View view) { final ViewGroup.LayoutParams lp = view.getLayoutParams(); final int originalHeight = view.getHeight(); ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 0); animator.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator arg0) { } @Override public void onAnimationRepeat(Animator arg0) { } @Override public void onAnimationEnd(Animator arg0) { lp.height = 0; view.setLayoutParams(lp); } @Override public void onAnimationCancel(Animator arg0) { } }); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { lp.height = (Integer) valueAnimator.getAnimatedValue(); view.setLayoutParams(lp); } }); return animator; } }