跳过自定义卡堆栈视图的动画

时间:2018-01-05 15:15:46

标签: java android android-layout animation android-custom-view

所以我的目标是做到这一点(不要看看毁容的布局,我只是删除了徽标):

sing in card photo

点击“注册”登录卡片向下滑动到屏幕,注册卡从底部开始:

register card photo

在第二个poto上的3张卡(所有卡片都是自定义视图)具有几乎相同的布局,并且每个向下滑动单击“继续”按钮

问题

将登录卡中的动画滑动到注册跳过。在卡片中唱歌完美地向下滑动,然后在~1秒内开始延迟并且注册卡在动画中滑动滑动并且刚出现。然而,从卡片上注册到卡片中的动画在两张卡片上都是正确的。

问题

如何解决从卡片中唱歌到注册的动画问题?

代码

这是所有卡片的paren类:

public abstract class CardStackView extends RelativeLayout {

protected CardStackListener cardStackListener;

public CardStackView(Context context) {
    super(context);
}

public CardStackView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
}

public CardStackView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public void setCardStackListener(CardStackListener cardStackListener) {
    this.cardStackListener = cardStackListener;
    cardStackListener.onCreated(this);
}

protected interface CardStackListener {
    void onCreated(CardStackView view);

    void onRemove();

    void onAdd();
}

public abstract void setShade(float value);

public abstract void enable();

public abstract void disable();

}

这是卡持卡人的类别,负责卡片切换:

public class CardStackFragmentView extends FrameLayout {

private static final int MARGIN = 10;
private static final float SCALE = .1f;
private static final float ALPHA = .1f;

private List<CardStackView> totalCards = new LinkedList<>();
private List<CardStackView> cards = new LinkedList<>();
private Handler cardHandler = new Handler();

public CardStackFragmentView(Context context) {
    super(context);
    Log.i(this.getClass().getName(), "CardStackFragmentView");
}

public CardStackFragmentView(Context context, AttributeSet attrs) {
    super(context, attrs);
    Log.i(this.getClass().getName(), "CardStackFragmentView");
}

/**
 * Adds cards from params to this card holder
 * and adds proper sizes and shade to be viewed like a card stack
 * @param cardStackViews cards for this card holder
 */
public void addCards(CardStackView... cardStackViews) {
    totalCards.addAll(Arrays.asList(cardStackViews));
    cards.addAll(Arrays.asList(cardStackViews));
    for (int i = cards.size() - 1; i >= 0; i--) {
        CardStackView card = cards.get(i);
        int offset = i;
        if (i == 0) {
            card.enable();
        } else {
            card.disable();
        }
        card.setCardStackListener(new CardStackView.CardStackListener() {
            @Override
            public void onCreated(CardStackView view) {
                view.animate()
                        .scaleX(1 - SCALE * offset)
                        .translationY(-MARGIN * offset);
                view.setShade(ALPHA * offset);
            }

            @Override
            public void onRemove() {
                removeFromTop();
            }

            @Override
            public void onAdd() {
                addCardToTop();
            }

        });
    }

    //I thought may be if i ll add cards in different threads it solves the problem

    for (int i = 0; i < cards.size(); i++) {
        int tmp = i;
        cardHandler.postDelayed(() -> addView(cards.get((cards.size() - 1 - tmp))), i * 20);
    }
}


/**
 * Adds card on top of stack and reanimates all cards in stack
 */
public void addCardToTop() {
    CardStackView fragment = totalCards.get(totalCards.size() - (cards.size() + 1));
    fragment.animate().translationY(-(fragment.getHeight() + 30));
    cards.add(0, fragment);
    fragment.enable();
    for (int i = 0; i < cards.size(); i++) {
        CardStackView card = cards.get(i);
        if (i == 0) {
            card.enable();
        } else {
            card.disable();
        }
        card.animate()
                .scaleX(1 - SCALE * i)
                .translationY(-MARGIN * i);
        card.setShade(ALPHA * i);
    }
}

public void removeFromTop() {
    Log.i(this.getClass().getName(), "removeFromTop");
    CardStackView fragment = cards.get(0);
    fragment.animate().translationY(fragment.getHeight() + 30);
    fragment.disable();
    cards.remove(0);
    for (int i = 0; i < cards.size(); i++) {
        CardStackView card = cards.get(i);
        if (i == 0) {
            card.enable();
        } else {
            card.disable();
        }
        card.animate()
                .scaleX(1 - SCALE * i)
                .translationY(-MARGIN * i);
        card.setShade(ALPHA * i);
    }
}

}

这是用于启动动画的onClick方法:

@OnClick(R.id.tv_login_register)
public void createAccountClicked(View view) {
    LoginActivity loginActivity = ((LoginActivity) getContext());
    RegisterCard registerCard = new RegisterCard(loginActivity);
    loginActivity.hideMenu();
    view.setEnabled(false);
    startAnimation(AnimationUtils.loadAnimation(loginActivity, R.anim.move_out));
    new Handler().postDelayed(
            () -> {
                loginActivity.getCardsRelativeLayout().removeView(LoginCard.this);
                loginActivity.getCardsRelativeLayout().addView(registerCard);
                registerCard.startAnimation(AnimationUtils.loadAnimation(loginActivity, R.anim.move_in));
            },
            400);
}

感谢您的时间。我希望这可以帮助你帮助我。)

1 个答案:

答案 0 :(得分:0)

问题不在我的自定义卡片堆栈视图中,而是在包含此视图的活动中(动画因为存在巨大的冻结而跳过)。它太沉重,布局深度很大。所以我只是点亮了活动的布局,滞后和冻结消失了=)所以这是结论:让你的xml布局尽可能轻盈。这是我复杂问题的简单答案。