【问题标题】:How to set animation on recyclerview如何在recyclerview上设置动画
【发布时间】:2015-01-06 06:54:18
【问题描述】:

我正在使用新的 API 21 (Lollipop) 创建一个应用程序,我在 recyclerview 上设置动画 slide_in_left 以使 cardview 1 乘 1 动画,但是当项目出现时,它们会聚集在一起,我希望它们以 1 乘 1 和 2 的方式滑动我正在制作动画工具栏栏隐藏/显示其工作但问题是当我向上滚动并且当recyclerview停止时它会隐藏并且向下滚动时相同的情况,我想在滚动开始时隐藏/显示工具栏任何人帮助我。提前致谢

下面是用于 recyclerview 动画的 Myadapter 类

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

private ArrayList<PersonData> peopleDataSet;
private Context context;
View view;
public static class MyViewHolder extends RecyclerView.ViewHolder {

    TextView textViewName;
    TextView textViewEmail;
    ImageView imageViewIcon;

    public MyViewHolder(View itemView) {
        super(itemView);
        this.textViewName = (TextView) itemView.findViewById(R.id.textViewName);
        this.textViewEmail = (TextView) itemView.findViewById(R.id.textViewEmail);
        this.imageViewIcon = (ImageView) itemView.findViewById(R.id.imageView);
    }
}

public MyAdapter(ArrayList<PersonData> people,Context context) {
    this.peopleDataSet = people;
    this.context=context;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
                                       int viewType) {
    view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.cards_layout, parent, false);

    view.setOnClickListener(MainActivity.myOnClickListener);
  setAnimation(view);
    MyViewHolder myViewHolder = new MyViewHolder(view);
    return myViewHolder;
}

@Override
public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {

    TextView textViewName = holder.textViewName;
    TextView textViewEmail = holder.textViewEmail;
    ImageView imageView = holder.imageViewIcon;

    textViewName.setText(peopleDataSet.get(listPosition).getName());
    textViewEmail.setText(peopleDataSet.get(listPosition).getEmail());
    imageView.setImageResource(peopleDataSet.get(listPosition).getImage());

}

@Override
public int getItemCount() {
    return peopleDataSet.size();
}
/**
 * Here is the key method to apply the animation
 */
private void setAnimation(View viewToAnimate)
{
    // If the bound view wasn't previously displayed on screen, it's animated
    Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
        viewToAnimate.startAnimation(animation);

}

下面是工具栏代码

@SuppressLint("NewApi") @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

            super.onScrolled(recyclerView, dx, dy);

            if (dy > 0) {
                toolbar.animate()
                        .translationY(-toolbar.getBottom())
                        .setInterpolator(new AccelerateInterpolator())
                        .start();



            } else {

                toolbar.animate()
                        .translationY(0)
                        .setInterpolator(new AccelerateInterpolator())
                        .start();


            }

【问题讨论】:

    标签: android animation android-recyclerview android-toolbar android-cardview


    【解决方案1】:

    很遗憾,RecyclerView 不支持使用RecyclerView.ItemAnimator 滚动时的动画。

    如果要实现 RecyclerView 项的一个一个动画,你应该在onBindView 方法中对每个viewHolder.itemView 进行动画处理。跟踪最后一个动画位置对于在向下滚动时避免动画很重要,除非这不是您的意图。

    这是我做的简单 alpha 动画:

    public interface RecyclerViewItemOnScrollAnimator {
        public void onAnimateViewHolder(RecyclerView.ViewHolder viewHolder, int position);
        public void onPrepareToAnimateViewHolder(RecyclerView.ViewHolder viewHolder);
    }
    

    这是Animator 的实现(有点,想不出更好的名字)

    public class RecyclerViewScrollAnimator implements RecyclerViewItemOnScrollAnimator{
        private final LinearLayoutManager mLayoutManager;
        private final RecyclerView mRecyclerView;
        private final Interpolator mInterpolator;
        int mLastAnimatedPosition = RecyclerView.NO_POSITION;
    
        public RecyclerViewScrollAnimator(RecyclerView recyclerView) {
            mLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            mRecyclerView = recyclerView;
            mInterpolator = InterpolatorUtil.loadInterpolator(recyclerView.getContext());
        }
    
        @Override
        public void onAnimateViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
            onPrepareToAnimateViewHolder(viewHolder);
            if(shouldAnimateOrPrepare(position)){
                ViewCompat.animate(viewHolder.itemView)
                        .alpha(1)
                        .setInterpolator(mInterpolator)
                        .setDuration(300).start();
            }
            mLastAnimatedPosition = position;
        }
    
        private boolean shouldAnimateOrPrepare(int position) {
           return mLastAnimatedPosition == RecyclerView.NO_POSITION || mLastAnimatedPosition < position;
        }
    
        @Override
        public void onPrepareToAnimateViewHolder(RecyclerView.ViewHolder viewHolder) {
         // do some stuff if needed before animation
         if(shouldAnimateOrPrepare(position)){
            ViewCompat.setAlpha(viewHolder.itemView, 0);
         }
        }
        //clear animation if needed
        private void cancelAnimationAt(int position) {
          RecyclerView.ViewHolder v =  mRecyclerView.findViewHolderForPosition(position);
          if(!isVisible(position) || v != null){
              if(v != null) {
                  Log.i("cancelAnimationAt", " canceling "+position);
                  //cancelAnimation(v.itemView);
              }
          }
    
        }
    
        private void cancelAnimation(View v) {
           if(v != null) {
            v.clearAnimation();
            v.setAnimation(null);
            ViewCompat.animate(v).cancel();
          }
        }
    
        private boolean isVisible(int position){
            return position >= mLayoutManager.findFirstVisibleItemPosition() && position <= mLayoutManager.findLastVisibleItemPosition();
        }
    
    }
    

    下面是你在RecyclerView.Adapter中使用它的方法

     @Override
        public void onBindViewHolder(RecyclerView.ViewHolder vh, int position) {
          if(getItemViewType(position) == VIEW_TYPE_ITEM) {
              bindItem(vh, position-1); // position only if no header otherwise position-1
              mRecyclerViewAnimator.onAnimateViewHolder(vh, position);
          }
          else return; // don't bind the header
        }
    

    现在您应该修改onAnimateViewHolder() 中的代码以使用您的动画资源。那是微不足道的。

    在你的Toolbar 切换时,我建议你使用这个library。它为您的目的提供了非常方便的滚动回调。

    【讨论】:

    • 您应该使用onViewAttachedToWindow 而不是onBind。 RecyclerView 不会重新绑定缓存且有效的项目。
    猜你喜欢
    • 1970-01-01
    • 2016-11-01
    • 2014-10-12
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    相关资源
    最近更新 更多