动画机器人/视图底部违反了recyclelerView的滚动

时间:2016-08-23 12:07:54

标签: android android-recyclerview android-animation android-scrollview

我有一个recyclerView,它包含一个自定义视图列表。当我单击recyclerView项时,它会被展开,提供更多信息。另一次点击此视图(或另一个视图)将关闭当前视图。提供SimpleItemAnimator的默认动画似乎不合适。所以,我试着像我一样自己实现animateChange

public class CustomItemAnimator extends CustomDefaultItemAnimator {

    private static final int FADE_IN = 1;
    private static final int FADE_OUT = 2;

    private ItemHolderInfo getItemHolderInfo(RecyclerView.ViewHolder viewHolder, MoveInfo moveInfo) {
        moveInfo.stuff.clear();
        ViewGroup content_container = (ViewGroup) viewHolder.itemView.findViewById(R.id.item_content);
        for (int i = 0; i < content_container.getChildCount(); i++) {
            View view = content_container.getChildAt(i);
            if (view.getVisibility() == View.VISIBLE) {
                moveInfo.stuff.put(view.getId(), new Pair<>(view.getTop(), view.getBottom()));
            }
        }
        moveInfo.stuff.put(viewHolder.itemView.getId(), new Pair<>(viewHolder.itemView.getTop(), viewHolder.itemView.getBottom()));
        moveInfo.stuff.put(content_container.getId(), new Pair<>(content_container.getTop(), content_container.getBottom()));
        return moveInfo;
    }

    @NonNull
    @Override
    public ItemHolderInfo recordPreLayoutInformation(@NonNull RecyclerView.State state, @NonNull RecyclerView.ViewHolder viewHolder, int changeFlags, @NonNull List<Object> payloads) {
        ItemHolderInfo info = super.recordPreLayoutInformation(state, viewHolder, changeFlags, payloads);
        return getItemHolderInfo(viewHolder, (MoveInfo) info);
    }


    @NonNull
    @Override
    public ItemHolderInfo recordPostLayoutInformation(@NonNull RecyclerView.State state, @NonNull RecyclerView.ViewHolder viewHolder) {
        MoveInfo info = (MoveInfo) super.recordPostLayoutInformation(state, viewHolder);
        return getItemHolderInfo(viewHolder, info);
    }

    @Override
    public boolean animateChange(@NonNull final RecyclerView.ViewHolder oldHolder, @NonNull final RecyclerView.ViewHolder newHolder, @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) {
        Log.d("ANIMATOR", "animate change called 2");
        MoveInfo pre = (MoveInfo) preInfo;
        MoveInfo post = (MoveInfo) postInfo;
        int fade_style;
        final HashMap<Integer, Pair<Integer, Integer>> minMap;
        HashMap<Integer, Pair<Integer, Integer>> maxMap;
        if (pre.stuff.keySet().size() <= post.stuff.keySet().size()) {
            minMap = pre.stuff;
            maxMap = post.stuff;
            fade_style = FADE_IN;
        } else {
            minMap = post.stuff;
            maxMap = pre.stuff;
            fade_style = FADE_OUT;
        }

        /*Getting the GoneViews*/
        HashMap<Integer, Pair<Integer, Integer>> goneViews = new HashMap<>();

        for (Integer i : maxMap.keySet()) {
            if (minMap.get(i) == null) {
                goneViews.put(i, maxMap.get(i));
            }
        }
        List<Animator> animators = new ArrayList<>();

        for (Integer i : minMap.keySet()) {
            ViewPropertyAnimatorCompat animView = ViewCompat.animate(newHolder.itemView.findViewById(i));
            ObjectAnimator viewDeltaTop = ObjectAnimator.ofInt(newHolder.itemView.findViewById(i), "top", pre.stuff.get(i).first, post.stuff.get(i).first);
            ObjectAnimator viewDeltaBot = ObjectAnimator.ofInt(newHolder.itemView.findViewById(i), "bottom", pre.stuff.get(i).second, post.stuff.get(i).second);
            animators.add(viewDeltaTop);
            animators.add(viewDeltaBot);
        }

        for (Integer i : goneViews.keySet()) {
            float from = fade_style == FADE_IN ? 0.0f : 1.0f;
            float to = fade_style == FADE_IN ? 1.0f : 0.0f;
            Animator viewAlpha = ObjectAnimator.ofFloat(newHolder.itemView.findViewById(i), "alpha", from, to);
            animators.add(viewAlpha);
        }
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(animators);
        animatorSet.setDuration(getChangeDuration());
        animatorSet.start();
        return true;
    }

    @Override
    public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull List<Object> payloads) {
        //to make viewholders reusable
        return true;
    }

    //we store our infos here
    private class MoveInfo extends ItemHolderInfo {
        HashMap<Integer, Pair<Integer, Integer>> stuff = new HashMap<>();
    }

    //not implementing this cause cast error in my case
    @Override
    public ItemHolderInfo obtainHolderInfo() {
        return new MoveInfo();
    }
}

除了一件事,这就像魅力一样。如果我尝试滚动,在更改动画时,动画视图无法正确显示。看起来好像动画的底部/顶部值不会通过滚动接收任何输入。我喜欢这种方式,itemAnimator有效,我想以这种方式使事情发挥作用。任何提示都表示赞赏。可能,我必须检查LinearLayoutManager?

0 个答案:

没有答案