1

我正在使用新的 API 21(Lollipop)创建一个应用程序我在 recyclerview 上设置动画 slide_in_left 以将 cardview 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();


            }
4

1 回答 1

4

不幸的是,RecyclerView在滚动时不支持动画RecyclerView.ItemAnimator

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

这是我做的简单的 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切换时,我建议您使用这个。它为您的目的提供了非常方便的滚动回调。

于 2015-01-08T23:36:04.413 回答