有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

所以我的目标是这样做(不要看变形的布局,我只是删除了徽标):

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) 个答案

  1. # 1 楼答案

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