Подтвердить что ты не робот

Что-то странное происходит при слишком быстрой прокрутке RecyclerView

Я использую RecyclerView для длинного списка, и когда я прокручиваю слишком быстро, происходит что-то странное. Есть две проблемы.

Первый - тот, что изображен ниже. Один из элементов (например, красный, ограниченный одним изображением) прикрепляется к некоторой случайной части экрана и блокирует другие элементы. Он исчезает, когда реальная версия этого элемента становится видимой на экране.

screenshot

Еще одна проблема с прокруткой этого длинного RecyclerView слишком быстро - это эффект onClick. Некоторые предметы становятся видимыми, как кто-то нажимает на них.

Являются ли эти проблемы с моим адаптером или являются ли они распространенными проблемами в RecyclerView? Вот мой адаптер:

public class SimpleListItemRecyclerAdapter extends RecyclerView.Adapter<SimpleListItemRecyclerAdapter.ListItemViewHolder> {

    Context context;
    ArrayList<RecyclerItemModel> list;
    OnRecyclerViewItemClickListener onRecyclerViewItemClickListener;
    private int lastPosition = -1;
    private boolean isClickable;

    public SimpleListItemRecyclerAdapter(ArrayList<RecyclerItemModel> list, _FragmentTemplate fragment) {
        this.list = list;
        this.context = fragment.getActivity();
        try {
            this.onRecyclerViewItemClickListener = (OnRecyclerViewItemClickListener) fragment;
            isClickable = true;
        } catch (ClassCastException e) {
            isClickable = false;
        }
        setHasStableIds(true);
    }

    @Override
    public ListItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).
                inflate(R.layout.item_sub_main_list_single_text,
                        parent,
                        false);
        return new ListItemViewHolder(itemView, onRecyclerViewItemClickListener, isClickable, list.get(0).getHeight());
    }

    @Override
    public void onBindViewHolder(ListItemViewHolder holder, int position) {
        final RecyclerItemModel recyclerItem = list.get(position);

        if (recyclerItem.isBackgroundColorSpecified())
            holder.itemView.setBackgroundResource(recyclerItem.getBackgroundColorResource());
        else {
            final int[] backgroundColors = Preferences.backgroundSelectorsGrey;
            holder.itemView.setBackgroundResource(backgroundColors[position % backgroundColors.length]);
        }

        holder.textMain.setText(recyclerItem.getTextMain());

        if (recyclerItem.isImageRightAvailable()) {
            if (recyclerItem.isProgressBarAvailable())
                if (recyclerItem.shouldShowDoneImage())
                    setDrawableFromSVG(holder.imageRight, recyclerItem.getImageRightResourceDone());
                else
                    setDrawableFromSVG(holder.imageRight, recyclerItem.getImageRightResource());
        } else
            holder.imageRight.setVisibility(View.GONE);

        if (recyclerItem.isTextMainBottomAvailable())
            holder.textMainBottom.setText(recyclerItem.getTextMainBottom());
        else
            holder.textMainBottom.setVisibility(View.GONE);

        if (recyclerItem.isTextRightTopAvailable())
            holder.textRightTop.setText(recyclerItem.getTextRightTop());
        else
            holder.textRightTop.setVisibility(View.GONE);

        if (recyclerItem.isTextRightBottomAvailable())
            holder.textRightBottom.setText(recyclerItem.getTextRightBottom());
        else
            holder.textRightBottom.setVisibility(View.GONE);

        if (recyclerItem.isProgressBarAvailable())
            holder.progressBar.setProgress(recyclerItem.getProgress());
        else
            holder.progressBar.setVisibility(View.GONE);

        setAnimation(holder.itemView, position);
    }

    @Override
    public long getItemId(int position) {
        return list.get(position).hashCode();
    }

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

    private void setAnimation(View viewToAnimate, int position) {
        if (position > lastPosition) {
            Animation animation = AnimationUtils.loadAnimation(context, R.anim.appear);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }

    public Drawable setDrawableFromSVG(ImageView imageView, int resource) {
        SVG svg = new SVGBuilder()
                .readFromResource(context.getResources(), resource)
                .build();
        imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        imageView.setImageDrawable(svg.getDrawable());
        return svg.getDrawable();
    }

    public final static class ListItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        OnRecyclerViewItemClickListener onRecyclerViewItemClickListener;
        TextView textMain, textMainBottom, textRightTop, textRightBottom;
        ImageView imageRight;
        ProgressBar progressBar;
        View itemView;

        public ListItemViewHolder(View itemView, OnRecyclerViewItemClickListener onRecyclerViewItemClickListener,
                                  boolean isClickable, int height) {
            super(itemView);
            this.itemView = itemView;
            this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener;

            textMain = (TextView) itemView.findViewById(R.id.list_item_text_main);
            imageRight = (ImageView) itemView.findViewById(R.id.list_item_image_right);
            textRightTop = (TextView) itemView.findViewById(R.id.list_item_text_right_top);
            textRightBottom = (TextView) itemView.findViewById(R.id.list_item_text_right_bottom);
            textMainBottom = (TextView) itemView.findViewById(R.id.list_item_text_main_bottom);
            progressBar = (ProgressBar) itemView.findViewById(R.id.list_item_progress_bar);

            switch (height) {
                case RecyclerItemModel.HEIGHT_FULL:
                        itemView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, Preferences.squareLength));
                    break;
                case RecyclerItemModel.HEIGHT_HALF:
                        itemView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, Preferences.squareLength / 2));
            }

            if (isClickable)
                itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            onRecyclerViewItemClickListener.onRecyclerViewItemClick(getPosition());
        }
    }
}
4b9b3361

Ответ 1

Вот что разрешило мою проблему:

Анимация как-то вызывает проблему в RecyclerView. Поэтому решение для меня заключалось в удалении следующей строки:

setAnimation(holder.itemView, position);

Я не пытался добавлять анимацию снова, но если вам это действительно нужно, вот что может быть полезно: Как оживить элементы RecyclerView, когда они появляются.