编排 - 为Recycler View推动动画

时间:2018-05-08 06:30:22

标签: android animation android-recyclerview material-design expandablerecyclerview

我正在尝试根据用户的操作动态地将元素插入到回收站视图中。在插入或删除元素时,我打算使用编排动画,其中输入元素上下推动其他元素。我打算做的动画可以通过以下链接访问

https://storage.googleapis.com/material-design/publish/material_v_12/assets/0B14F_FSUCc01RFdjQWE4ZXBseWM/aware-02-moveaway-v2.mp4

如果我提供了关于如何继续使用此类动画的预测,那将非常有用。

1 个答案:

答案 0 :(得分:0)

试试这个:

public class AdapterRow extends RecyclerView.Adapter<AdapterPosliteNamFoto.ItemHolder> {

    private final ArrayList<DataHolder> array;

    public AdapterRow() {
        this.array = new ArrayList<>();
        this.array.add(new DataHolder("Text 1"));
        this.array.add(new DataHolder("Text 2"));
        this.array.add(new DataHolder("Text 3"));
    }

    @Override
    public int getItemCount() {
        return (null != array ? array.size() : 0);
    }

    @NonNull
    @Override
    public ItemHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new ItemHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_row, viewGroup, false));
    }

    @Override
    public void onBindViewHolder(@NonNull final ItemHolder holder, int position) {
        DataHolder model = array.get(position);
        holder.txt.setText(model.txt);

        holder.rootLt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int pos = holder.getAdapterPosition();
                if (pos != RecyclerView.NO_POSITION) {
                    DataHolder model = array.get(pos);

                    if (model.rowState == RowState.EXPANDED) {
                        changeRowState(holder, pos, model, RowState.COLLAPSING);
                    } else if (model.rowState == RowState.COLLAPSED) {
                        changeRowState(holder, pos, model, RowState.EXPANDING);
                    }
                }
            }
        });
    }

    public void changeRowState(ItemHolder holder, int pos, DataHolder model, @RowState int rowState) {
        model.rowState = rowState;
        array.set(pos, model);

        final View v = holder.rootLt;

        if (rowState == RowState.EXPANDING) {
            v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            final int targetHeight = v.getMeasuredHeight() * 2;

            v.getLayoutParams().height = 1;
            v.setVisibility(View.VISIBLE);

            ValueAnimator va = ValueAnimator.ofInt(1, targetHeight);
            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                public void onAnimationUpdate(ValueAnimator animation) {
                    v.getLayoutParams().height = (Integer) animation.getAnimatedValue();
                    v.requestLayout();
                }
            });
            va.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    v.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
                }

                @Override public void onAnimationStart(Animator animation) {}
                @Override public void onAnimationCancel(Animator animation) {}
                @Override public void onAnimationRepeat(Animator animation) {}
            });
            va.setDuration(300);
            va.setInterpolator(new OvershootInterpolator());
            va.start();
        } else if (rowState == RowState.COLLAPSING) {
            final int initialHeight = v.getMeasuredHeight();

            ValueAnimator va = ValueAnimator.ofInt(initialHeight, initialHeight / 2);
            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                public void onAnimationUpdate(ValueAnimator animation) {
                    v.getLayoutParams().height = (Integer) animation.getAnimatedValue();
                    v.requestLayout();
                }
            });
            va.setDuration(300);
            va.setInterpolator(new DecelerateInterpolator());
            va.start();
        }
    }

    public class ItemHolder extends RecyclerView.ViewHolder {

        protected ViewGroup rootLt;
        protected TextView txt;

        public ItemHolder(View view) {
            super(view);
            this.rootLt = view.findViewById(R.id.root_layout);
            this.txt = view.findViewById(R.id.txt);
        }
    }

    @IntDef(value = {
            RowState.COLLAPSED, RowState.COLLAPSING, RowState.EXPANDED, RowState.EXPANDING})
    @Retention(RetentionPolicy.SOURCE)
    public @interface RowState {
        int COLLAPSED = 0;
        int COLLAPSING = 1;
        int EXPANDED = 2;
        int EXPANDING = 3;
    }

    public class DataHolder {
        public String text;
        @RowState
        public int rowState = RowState.Collapsed;

        public DataHolder(String text) {
            this.text = text;
        }
    }

}