lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/animateaddition/AnimateAdditionAdapter.java
public void insert(@NonNull final Iterable<Pair<Integer, T>> indexItemPairs) {
        if (getListViewWrapper() == null) {
            throw new IllegalStateException("Call setListView on this AnimateAdditionAdapter!");
        }

        Collection<Pair<Integer, T>> visibleViews = new ArrayList<>();
        Collection<Integer> insertedPositions = new ArrayList<>();
        Collection<Integer> insertedBelowPositions = new ArrayList<>();

        int scrollDistance = 0;
        int numInsertedAbove = 0;

        for (Pair<Integer, T> pair : indexItemPairs) {
            if (getListViewWrapper().getFirstVisiblePosition() > pair.first) {
                /* Inserting an item above the first visible position */
                int index = pair.first;

                /* Correct the index for already inserted positions above the first visible view. */
                for (int insertedPosition : insertedPositions) {
                    if (index >= insertedPosition) {
                        index++;
                    }
                }

                mInsertable.add(index, pair.second);
                insertedPositions.add(index);
                numInsertedAbove++;

                if (mShouldAnimateDown) {
                    View view = getView(pair.first, null, getListViewWrapper().getListView());
                    view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                    scrollDistance -= view.getMeasuredHeight();
                }
            } else if (getListViewWrapper().getLastVisiblePosition() >= pair.first || getListViewWrapper().getLastVisiblePosition() == AdapterView.INVALID_POSITION ||
                    !childrenFillAbsListView()) {
                /* Inserting an item that becomes visible on screen */
                int index = pair.first;

                /* Correct the index for already inserted positions above the first visible view */
                for (int insertedPosition : insertedPositions) {
                    if (index >= insertedPosition) {
                        index++;
                    }
                }
                Pair<Integer, T> newPair = new Pair<>(index, pair.second);
                visibleViews.add(newPair);
            } else {
                /* Inserting an item below the last visible item */
                int index = pair.first;

                /* Correct the index for already inserted positions above the first visible view */
                for (int insertedPosition : insertedPositions) {
                    if (index >= insertedPosition) {
                        index++;
                    }
                }

                /* Correct the index for already inserted positions below the last visible view */
                for (int queuedPosition : insertedBelowPositions) {
                    if (index >= queuedPosition) {
                        index++;
                    }
                }

                insertedBelowPositions.add(index);
                mInsertable.add(index, pair.second);
            }
        }

        if (mShouldAnimateDown) {
            ((AbsListView) getListViewWrapper().getListView()).smoothScrollBy(scrollDistance, (int) (mScrolldownAnimationDurationMs * numInsertedAbove));
        }

        mInsertQueue.insert(visibleViews);

        int firstVisiblePosition = getListViewWrapper().getFirstVisiblePosition();
        View firstChild = getListViewWrapper().getChildAt(0);
        int childTop = firstChild == null ? 0 : firstChild.getTop();
        ((ListView) getListViewWrapper().getListView()).setSelectionFromTop(firstVisiblePosition + numInsertedAbove, childTop);
    }
public void insert(@NonNull final Iterable<Pair<Integer, T>> indexItemPairs) {
        if (getListViewWrapper() == null) {
            throw new IllegalStateException("Call setListView on this AnimateAdditionAdapter!");
        }

        Collection<Pair<Integer, T>> visibleViews = new ArrayList<>();
        Collection<Integer> insertedPositions = new ArrayList<>();
        Collection<Integer> insertedBelowPositions = new ArrayList<>();

        int scrollDistance = 0;
        int numInsertedAbove = 0;

        for (Pair<Integer, T> pair : indexItemPairs) {
            if (getListViewWrapper().getFirstVisiblePosition() > pair.first) {
                /* Inserting an item above the first visible position */
                int index = pair.first;

                /* Correct the index for already inserted positions above the first visible view. */
                for (int insertedPosition : insertedPositions) {
                    if (index >= insertedPosition) {
                        index++;
                    }
                }

                mInsertable.add(index, pair.second);
                insertedPositions.add(index);
                numInsertedAbove++;

                if (mShouldAnimateDown) {
                    View view = getView(pair.first, null, getListViewWrapper().getListView());
                    view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                    scrollDistance -= view.getMeasuredHeight();
                }
            } else if (getListViewWrapper().getLastVisiblePosition() >= pair.first || getListViewWrapper().getLastVisiblePosition() == AdapterView.INVALID_POSITION ||
                    !childrenFillAbsListView()) {
                /* Inserting an item that becomes visible on screen */
                int index = pair.first;

                /* Correct the index for already inserted positions above the first visible view */
                for (int insertedPosition : insertedPositions) {
                    if (index >= insertedPosition) {
                        index++;
                    }
                }
                Pair<Integer, T> newPair = new Pair<>(index, pair.second);
                visibleViews.add(newPair);
            } else {
                /* Inserting an item below the last visible item */
                int index = pair.first;

                /* Correct the index for already inserted positions above the first visible view */
                for (int insertedPosition : insertedPositions) {
                    if (index >= insertedPosition) {
                        index++;
                    }
                }

                /* Correct the index for already inserted positions below the last visible view */
                for (int queuedPosition : insertedBelowPositions) {
                    if (index >= queuedPosition) {
                        index++;
                    }
                }

                insertedBelowPositions.add(index);
                mInsertable.add(index, pair.second);
            }
        }

        if (mShouldAnimateDown) {
            ((AbsListView) getListViewWrapper().getListView()).smoothScrollBy(scrollDistance, (int) (mScrolldownAnimationDurationMs * numInsertedAbove));
        }

        mInsertQueue.insert(visibleViews);

        int firstVisiblePosition = getListViewWrapper().getFirstVisiblePosition();
        View firstChild = getListViewWrapper().getChildAt(0);
        int childTop = firstChild == null ? 0 : firstChild.getTop();
        ((ListView) getListViewWrapper().getListView()).setSelectionFromTop(firstVisiblePosition + numInsertedAbove, childTop);
    }
public void insert ( @ NonNull final Iterable < Pair < Integer , T > > indexItemPairs ) { if ( getListViewWrapper ( ) == null ) { throw new IllegalStateException ( "Call setListView on this AnimateAdditionAdapter!" ) ; } Collection < Pair < Integer , T > > visibleViews = new ArrayList <> ( ) ; Collection < Integer > insertedPositions = new ArrayList <> ( ) ; Collection < Integer > insertedBelowPositions = new ArrayList <> ( ) ; int scrollDistance = 0 ; int numInsertedAbove = 0 ; for ( Pair < Integer , T > pair : indexItemPairs ) { if ( getListViewWrapper ( ) . getFirstVisiblePosition ( ) > pair . first ) { /* Inserting an item above the first visible position */ int index = pair . first ; /* Correct the index for already inserted positions above the first visible view. */ for ( int insertedPosition : insertedPositions ) { if ( index >= insertedPosition ) { index ++ ; } } mInsertable . add ( index , pair . second ) ; insertedPositions . add ( index ) ; numInsertedAbove ++ ; if ( mShouldAnimateDown ) { View view = getView ( pair . first , null , getListViewWrapper ( ) . getListView ( ) ) ; view . measure ( View . MeasureSpec . makeMeasureSpec ( 0 , View . MeasureSpec . UNSPECIFIED ) , View . MeasureSpec . makeMeasureSpec ( 0 , View . MeasureSpec . UNSPECIFIED ) ) ; scrollDistance -= view . getMeasuredHeight ( ) ; } } else if ( getListViewWrapper ( ) . getLastVisiblePosition ( ) >= pair . first || getListViewWrapper ( ) . getLastVisiblePosition ( ) == AdapterView . INVALID_POSITION || ! childrenFillAbsListView ( ) ) { /* Inserting an item that becomes visible on screen */ int index = pair . first ; /* Correct the index for already inserted positions above the first visible view */ for ( int insertedPosition : insertedPositions ) { if ( index >= insertedPosition ) { index ++ ; } } Pair < Integer , T > newPair = new Pair <> ( index , pair . second ) ; visibleViews . add ( newPair ) ; } else { /* Inserting an item below the last visible item */ int index = pair . first ; /* Correct the index for already inserted positions above the first visible view */ for ( int insertedPosition : insertedPositions ) { if ( index >= insertedPosition ) { index ++ ; } } /* Correct the index for already inserted positions below the last visible view */ for ( int queuedPosition : insertedBelowPositions ) { if ( index >= queuedPosition ) { index ++ ; } } insertedBelowPositions . add ( index ) ; mInsertable . add ( index , pair . second ) ; } } if ( mShouldAnimateDown ) { ( ( AbsListView ) getListViewWrapper ( ) . getListView ( ) ) . smoothScrollBy ( scrollDistance , ( int ) ( mScrolldownAnimationDurationMs * numInsertedAbove ) ) ; } mInsertQueue . insert ( visibleViews ) ; int firstVisiblePosition = getListViewWrapper ( ) . getFirstVisiblePosition ( ) ; View firstChild = getListViewWrapper ( ) . getChildAt ( 0 ) ; int childTop = firstChild == null ? 0 : firstChild . getTop ( ) ; ( ( ListView ) getListViewWrapper ( ) . getListView ( ) ) . setSelectionFromTop ( firstVisiblePosition + numInsertedAbove , childTop ) ; }
Inserts items at given indexes. Will show an entrance animation for the new items if the newly added item is visible.
Will also call {@link Insertable#add(int, Object)} of the root {@link android.widget.BaseAdapter}.

@param indexItemPairs the index-item pairs to insert. The first argument of the {@code Pair} is the index, the second argument is the item.
Inserts items at given indexes . Will show an entrance animation for the new items if the newly added item is visible . Will also call { @link Insertable#add ( int Object ) } of the root { @link android . widget . BaseAdapter } .