private void bringToFrontByZIndex() {
        if (mAnimType == InfiniteCardView.ANIM_TYPE_FRONT) {
            //if the animation type is ANIM_TYPE_FRONT, which means other cards are under common
            // animation, so start cycling the card items from the position before the moving
            // card, and while the moving card's Z index is smaller than an other card, we
            // call bringToFront for it, otherwise we call bringToFront for other cards
            for (int i = mPositionToFront - 1; i >= 0; i--) {
                CardItem card = mCards.get(i);
                if (card.zIndex > mCardToFront.zIndex) {
                    mCardToFront.view.bringToFront();
                    mCardView.updateViewLayout(mCardToFront.view, mCardToFront.view.getLayoutParams());
                } else {
                    card.view.bringToFront();
                    mCardView.updateViewLayout(card.view, card.view.getLayoutParams());
                }
            }
        } else {
            //sort the card items by Z index and call bringToFront foreach view
//            Collections.sort(mCards4JudgeZIndex, this);
//            for (int i = mCardCount - 1; i >= 0; i--) {
//                mCards4JudgeZIndex.get(i).view.bringToFront();
//            }
            //##########################for better performance#########################
            boolean cardToFrontBrought = false;//is card moving to front called bringToFront
            //cycling the card items
            for (int i = mCardCount - 1; i > 0; i--) {
                CardItem card = mCards.get(i);
                //get the card before current card
                CardItem cardPre = i > 1 ? mCards.get(i - 1) : null;
                //is card moving to back behind the card before current card
                boolean cardToBackBehindCardPre = cardPre == null ||
                        mCardToBack.zIndex > cardPre.zIndex;
                //if the card moving to back Z index is smaller than current card, and is behind
                // the card before current card, we should call bringToFront for it
                boolean bringCardToBackViewToFront = mCardToBack.zIndex < card.zIndex && cardToBackBehindCardPre;
                //is card moving to front behind the current card
                boolean cardToFrontBehindCardPre = cardPre == null ||
                        mCardToFront.zIndex > cardPre.zIndex;
                //if the card moving to front Z index is smaller than current card, and is behind
                // the card before current card, we should call bringToFront for it
                boolean bringCardToFrontViewToFront = mCardToFront.zIndex < card.zIndex && cardToFrontBehindCardPre;
                //if current card is not the card moving to front
                if (i != mPositionToFront) {
                    //call bringToFront for it
                    card.view.bringToFront();
                    mCardView.updateViewLayout(card.view, card.view.getLayoutParams());
                    //if we should bring the card moving to back to front, just do it
                    if (bringCardToBackViewToFront) {
                        mCardToBack.view.bringToFront();
                        mCardView.updateViewLayout(mCardToBack.view, mCardToBack.view.getLayoutParams());
                    }
                    //if we should bring the card moving to front to front, just do it
                    if (bringCardToFrontViewToFront) {
                        mCardToFront.view.bringToFront();
                        mCardView.updateViewLayout(mCardToFront.view, mCardToFront.view.getLayoutParams());
                        cardToFrontBrought = true;
                    }
                    //if we has both bring the card moving to front and back to front, and the
                    // card moving to back Z index is smaller than the card moving to front Z
                    // index, we call bringToFront for the card moving to back
                    if (bringCardToBackViewToFront && bringCardToFrontViewToFront &&
                            mCardToBack.zIndex < mCardToFront.zIndex) {
                        mCardToBack.view.bringToFront();
                        mCardView.updateViewLayout(mCardToBack.view, mCardToBack.view.getLayoutParams());
                    }
                } else {
                    //if current card is the card moving to front, and behind the card before
                    if (cardToFrontBehindCardPre) {
                        mCardToFront.view.bringToFront();
                        mCardView.updateViewLayout(mCardToFront.view, mCardToFront.view.getLayoutParams());
                        cardToFrontBrought = true;
                        //if the card moving to back Z index is smaller than the card moving to
                        // front, call bringToFront for it
                        if (cardToBackBehindCardPre && mCardToBack.zIndex < mCardToFront.zIndex) {
                            mCardToBack.view.bringToFront();
                            mCardView.updateViewLayout(mCardToBack.view, mCardToBack.view.getLayoutParams());
                        }
                    }
                }
            }
            // it the card moving to front has not call bringToFront yet, which means it is
            // already in the first position, call bringToFront for it
            if (!cardToFrontBrought) {
                mCardToFront.view.bringToFront();
                mCardView.updateViewLayout(mCardToFront.view, mCardToFront.view.getLayoutParams());
            }
        }
    }
bring card to front by Z index, the card with smaller Z index is in front of the card with
bigger Z index
infinite-cards/src/main/java/com/bakerj/infinitecards/CardAnimationHelper.java