Android recyclerView 在滚动条上复制项目

Android recyclerView duplicates items on scroll

我正在使用 ViewHolder 模式并将自定义视图动态添加到 viewHolder。 自定义视图(MetroImageView)在滚动时重复。 我的适配器代码是:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
     private static final String TAG = MyAdapter.class.getSimpleName();
     public static List<Post> postsDataset;
     private int lastPosition = -1;
     private int delta = 0;
     private Context ctx;

public class ViewHolder extends RecyclerView.ViewHolder {

    //public final MetroImageView metroImage;
    public final RelativeLayout rootView;
    public final TextView amountTxt;
    public final TextView locationTxt;
    public final TextView titleTxt;
    public final TextView nameTxt;
    public final TextView likesTxt;
    public final TextView viewsTxt;
    public final TextView commentsTxt;
    public final ImageButton likesBtn;
    public final ImageButton commentsBtn;
    public final ImageButton viewsBtn;
    public final SimpleDraweeView tileImage;
    public boolean hasLike;

    public ViewHolder(final View sv) {
        super(sv);
        rootView = (RelativeLayout) sv.findViewById(R.id.statusLayout);
        amountTxt = (TextView) sv.findViewById(R.id.amountTxt);
        locationTxt = (TextView) sv.findViewById(R.id.locationTxt);
        titleTxt = (TextView) sv.findViewById(R.id.titleTxt);
        likesTxt = (TextView) sv.findViewById(R.id.likesTxt);
        viewsTxt = (TextView) sv.findViewById(R.id.viewsTxt);
        commentsTxt = (TextView) sv.findViewById(R.id.commentsTxt);
        tileImage = (SimpleDraweeView) sv.findViewById(R.id.tileImage);
        nameTxt = (TextView) sv.findViewById(R.id.nameTxt);
        //metroImage = (MetroImageView) sv.findViewById(R.id.metroImage);
        likesBtn = (ImageButton) sv.findViewById(R.id.likesBtn);
        viewsBtn = (ImageButton) sv.findViewById(R.id.viewsBtn);
        commentsBtn = (ImageButton) sv.findViewById(R.id.commentsBtn);
    }
}

public MyAdapter(List<Post> posts, Context context) {
    postsDataset = posts;
    ctx = context;
}

@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                     int viewType) {
    // create a new view
    View sv = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_tile, parent, false);
    return new ViewHolder(sv);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    List<Uri> imagesUrls = new ArrayList<>();
    holder.tileImage.setImageURI(null);

    MetroImageView metro = new MetroImageView(ctx);
    holder.rootView.removeView(metro);

    if (postsDataset.get(position).getMedia().size() > 0) {
        for (RealmString m : postsDataset.get(position).getMedia()) {
            Uri uri = Uri.parse(SweefitUtils.getImageUrlWithIdAndSize(m.getValue(), 5));
            imagesUrls.add(uri);
        }
        if(imagesUrls.size() > 1){
            metro = new MetroImageView(ctx);
            metro.setImagesUrls(imagesUrls);
            holder.rootView.removeView(metro);
            holder.rootView.addView(metro);
            holder.rootView.removeView(holder.tileImage);
        }
        else {
            holder.tileImage.setImageURI(imagesUrls.get(0));
        }
    }
    else if(postsDataset.get(position).getThumbnailUrl() != null) {
        imagesUrls.add(Uri.parse(postsDataset.get(position).getThumbnailUrl()));
        holder.tileImage.setImageURI(imagesUrls.get(0));
    }
    else{
        imagesUrls.add(Uri.parse(""));
        holder.tileImage.setImageURI(imagesUrls.get(0));
    }

    holder.amountTxt.setText("");
    if (postsDataset.get(position).getDesc() != null)
        holder.locationTxt.setText(postsDataset.get(position).getDesc());
    else
        holder.locationTxt.setText("");
    if (postsDataset.get(position).getTitle() != null)
        holder.titleTxt.setText(postsDataset.get(position).getTitle());
    else
        holder.titleTxt.setText("");
    if (postsDataset.get(position).getOwnerName() != null)
        holder.nameTxt.setText(postsDataset.get(position).getOwnerName());
    else
        holder.nameTxt.setText("");
    holder.likesTxt.setText(String.valueOf(postsDataset.get(position).getLikes()));
    holder.viewsTxt.setText(String.valueOf(postsDataset.get(position).getViews()));
    holder.commentsTxt.setText(String.valueOf(postsDataset.get(position).getTotalComments()));
    holder.hasLike = postsDataset.get(position).getHasLike();
}

@Override
public long getItemId(int position) {
    return position;
}


@Override
public int getItemCount() {
    return postsDataset.size();
}
}

MetroImageView 代码:

public class MetroImageView 扩展 RelativeLayout {

private SimpleDraweeView img1;
private SimpleDraweeView img2;

private List<Uri> imagesUrls = new ArrayList<>();
private final Random rand = new Random();
private int counter = 1;
private int i = 1;

public MetroImageView(Context context) {
    super(context);
    init(context);
}

public MetroImageView(Context context, AttributeSet as) {
    super(context, as);
    init(context);
}

private void init(Context context) {
    inflate(context, R.layout.metro_image_view, this);
    img1 = (SimpleDraweeView) findViewById(R.id.img1);
    img2 = (SimpleDraweeView) findViewById(R.id.img2);
    img1.setImageURI(Uri.parse(""));
    img2.setImageURI(Uri.parse(""));
}

public List<Uri> getImagesUrls() {
    return imagesUrls;
}

public void setImagesUrls(List<Uri> imagesUrls) {
    if(imagesUrls != null)
        this.imagesUrls = imagesUrls;
    animationManager();
}

private void flipUpAnimation(final Uri uri) {
    if(counter % 2 == 0){
        img1.setImageURI(uri);
        img1.animate().alpha(0).setDuration(0).setListener(null);
        img1.setX(0);
        img1.setY(0);
        img1.setRotationX(270);
        img2.setX(0);
        img2.setY(0);
        img2.setRotationX(0);
        img2.animate().rotationX(90).setDuration(1000).setListener(new Animator.AnimatorListener() {
                                                                           @Override
                                                                           public void onAnimationStart(Animator animation) {
                                                                               img1.animate().alpha(1).setListener(null);
                                                                           }

                                                                           @Override
                                                                           public void onAnimationEnd(Animator animation) {
                                                                               img2.animate().alpha(0).rotationX(0).setDuration(0).setListener(null);
                                                                               img1.animate().rotationX(360).setDuration(1000).setListener(new Animator.AnimatorListener() {
                                                                                   @Override
                                                                                   public void onAnimationStart(Animator animation) {
                                                                                   }

                                                                                   @Override
                                                                                   public void onAnimationEnd(Animator animation) {
                                                                                       timer();
                                                                                       img1.animate().setListener(null);
                                                                                   }

                                                                                   @Override
                                                                                   public void onAnimationCancel(Animator animation) {

                                                                                   }

                                                                                   @Override
                                                                                   public void onAnimationRepeat(Animator animation) {

                                                                                   }
                                                                               });
                                                                           }

                                                                           @Override
                                                                           public void onAnimationCancel(Animator animation) {

                                                                           }

                                                                           @Override
                                                                           public void onAnimationRepeat(Animator animation) {

                                                                           }
                                                                       }

        );
    }
    else{
        img2.setImageURI(uri);
        img2.animate().alpha(0).setDuration(0).setListener(null);
        img2.setX(0);
        img2.setY(0);
        img2.setRotationX(270);
        img1.setX(0);
        img1.setY(0);
        img1.setRotationX(0);
        img1.animate().rotationX(90).setDuration(1000).setListener(new Animator.AnimatorListener() {
                                                                       @Override
                                                                       public void onAnimationStart(Animator animation) {
                                                                           img2.animate().alpha(1).setListener(null);
                                                                       }

                                                                       @Override
                                                                       public void onAnimationEnd(Animator animation) {
                                                                           img1.animate().alpha(0).rotationX(0).setDuration(0).setListener(null);
                                                                           img2.animate().rotationX(360).setDuration(1000).setListener(new Animator.AnimatorListener() {
                                                                               @Override
                                                                               public void onAnimationStart(Animator animation) {
                                                                               }

                                                                               @Override
                                                                               public void onAnimationEnd(Animator animation) {
                                                                                   timer();
                                                                                   img2.animate().setListener(null);
                                                                               }

                                                                               @Override
                                                                               public void onAnimationCancel(Animator animation) {

                                                                               }

                                                                               @Override
                                                                               public void onAnimationRepeat(Animator animation) {

                                                                               }
                                                                           });
                                                                       }

                                                                       @Override
                                                                       public void onAnimationCancel(Animator animation) {

                                                                       }

                                                                       @Override
                                                                       public void onAnimationRepeat(Animator animation) {

                                                                       }
                                                                   }

        );
    }

}

private void flipDownAnimation(final Uri uri) {
    if(counter % 2 == 0){
        img1.setImageURI(uri);
        img1.animate().alpha(0).setDuration(0).setListener(null);
        img1.setX(0);
        img1.setY(0);
        img1.setRotationX(-270);
        img2.setX(0);
        img2.setY(0);
        img2.setRotationX(0);
        img2.animate().rotationX(-90).setDuration(1000).setListener(new Animator.AnimatorListener() {
                                                                       @Override
                                                                       public void onAnimationStart(Animator animation) {
                                                                           img1.animate().alpha(1).setListener(null);
                                                                       }

                                                                       @Override
                                                                       public void onAnimationEnd(Animator animation) {
                                                                           img2.animate().alpha(0).rotationX(0).setDuration(0).setListener(null);
                                                                           img1.animate().rotationX(-360).setDuration(1000).setListener(new Animator.AnimatorListener() {
                                                                               @Override
                                                                               public void onAnimationStart(Animator animation) {
                                                                               }

                                                                               @Override
                                                                               public void onAnimationEnd(Animator animation) {
                                                                                   timer();
                                                                                   img1.animate().setListener(null);
                                                                               }

                                                                               @Override
                                                                               public void onAnimationCancel(Animator animation) {

                                                                               }

                                                                               @Override
                                                                               public void onAnimationRepeat(Animator animation) {

                                                                               }
                                                                           });
                                                                       }

                                                                       @Override
                                                                       public void onAnimationCancel(Animator animation) {

                                                                       }

                                                                       @Override
                                                                       public void onAnimationRepeat(Animator animation) {

                                                                       }
                                                                   }

        );
    }
    else{
        img2.setImageURI(uri);
        img2.animate().alpha(0).setDuration(0).setListener(null);
        img2.setX(0);
        img2.setY(0);
        img2.setRotationX(-270);
        img1.setX(0);
        img1.setY(0);
        img1.setRotationX(0);
        img1.animate().rotationX(-90).setDuration(1000).setListener(new Animator.AnimatorListener() {
                                                                       @Override
                                                                       public void onAnimationStart(Animator animation) {
                                                                           img2.animate().alpha(1).setListener(null);
                                                                       }

                                                                       @Override
                                                                       public void onAnimationEnd(Animator animation) {
                                                                           img1.animate().alpha(0).rotationX(0).setDuration(0).setListener(null);
                                                                           img2.animate().rotationX(-360).setDuration(1000).setListener(new Animator.AnimatorListener() {
                                                                               @Override
                                                                               public void onAnimationStart(Animator animation) {
                                                                               }

                                                                               @Override
                                                                               public void onAnimationEnd(Animator animation) {
                                                                                   timer();
                                                                                   img2.animate().setListener(null);
                                                                               }

                                                                               @Override
                                                                               public void onAnimationCancel(Animator animation) {

                                                                               }

                                                                               @Override
                                                                               public void onAnimationRepeat(Animator animation) {

                                                                               }
                                                                           });
                                                                       }

                                                                       @Override
                                                                       public void onAnimationCancel(Animator animation) {

                                                                       }

                                                                       @Override
                                                                       public void onAnimationRepeat(Animator animation) {

                                                                       }
                                                                   }

        );
    }

}
public void animationManager() {
    if(imagesUrls.size() > 0) {
        img1.setImageURI(imagesUrls.get(0));
        timer();
    }
}

public void timer() {
    final Handler handler = new Handler();
    final Runnable r = new Runnable() {
        public void run() {
            if (i >= imagesUrls.size())
                i = 0;

            switch (rand.nextInt(9)) {
                case 0:
                    flipUpAnimation(imagesUrls.get(i));
                    break;
                case 1:
                    flipDownAnimation(imagesUrls.get(i));
                    break;
                case 2:
                    alphaAnimation(imagesUrls.get(i));
                    break;
                case 3:
                    slideRight(imagesUrls.get(i));
                    break;
                case 4:
                    slideLeft(imagesUrls.get(i));
                    break;
                case 5:
                    slideUp(imagesUrls.get(i));
                    break;
                case 6:
                    slideDown(imagesUrls.get(i));
                    break;
                case 7:
                    flipLeftAnimation(imagesUrls.get(i));
                    break;
                case 8:
                    flipRightAnimation(imagesUrls.get(i));
                    break;
            }
            i++;
            counter++;
        }
    };

    handler.postDelayed(r, 3000);
}

}

metro_image_view.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/img1"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:scaleType="fitXY"/>

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/img2"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:scaleType="fitXY"/>

我知道我必须重置每个视图(我在使用 ImageView 时遇到了同样的问题),但我不明白为什么 MetroImageView 会出现这种情况。 有什么想法吗?

如果有人想知道我在 xml 和 onBindViewHolder 上将 MetroImageView 更改为静态视图,而我不需要使用 MetroImageView 我只是这样做了:

holder.metroImage.setImagesUrls(null);
holder.metroImage.setVisibility(View.GONE);

现在完美了!