滚动RecyclerView太快时发生了一些奇怪的事情

时间:2015-01-28 12:45:04

标签: android android-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());
        }
    }
}

1 个答案:

答案 0 :(得分:6)

以下是解决我问题的原因:

以某种方式制作动画会导致RecyclerView出现问题。所以我的解决方案是删除以下行:

setAnimation(holder.itemView, position);

我没有尝试再次添加动画,但如果你真的需要它,可以使用以下内容:How to animate RecyclerView items when they appear