Recyclerview滞后于滚动

时间:2015-04-16 09:08:05

标签: android

我正在使用Recyclerview Gridlayout,我在滚动时面临滞后。

由于我使用的是RecyclerView.Adapter ViewHolder已经存在。

除此之外,onBindViewHolder中没有条件,即onCreateView方法。

此外,我确保不会创建新对象。

我正在使用Universal imageloader,我也在滚动上暂停了recyclerview imageloader。

我发现磁盘内存上的图像大小从50到300 kb不等,这与滚动速度有什么关系?

public class DealsRecyclerAdapter extends RecyclerView.Adapter<DealsRecyclerAdapter.ViewHolder> {
public ArrayList<DealItem> items = new ArrayList<DealItem>();
Context context;
DisplayImageOptions options;
protected ImageLoader imageLoader;
DealItemOnClickListener dealItemOnClickListener;

private static final String RESULTS = "results";

int layoutId;
DealItem item;
String storeName;
public static final String RS = "Rs.";
public static final String AVAIL_FROM = "available from ";
public static final String OFF = "% off";

static class ViewHolder extends RecyclerView.ViewHolder {

    protected TextView itemName;
    protected TextView itemPriceOrig;
    protected TextView itemDisc;
    protected TextView itemPrice;
    protected ImageView itemImage;
    protected TextView itemStore;
    protected TextView itemSpecialText;


    public ViewHolder(View itemView) {
        super(itemView);
        itemImage = (ImageView) itemView
                .findViewById(R.id.logo);
        itemName = ((CustomTextView) itemView
                .findViewById(R.id.title_product_search));
        itemPriceOrig = ((CustomTextView) itemView
                .findViewById(R.id.price_product_orig));
        itemDisc = ((CustomTextView) itemView
                .findViewById(R.id.product_disc));
        itemPrice = ((CustomTextView) itemView
                .findViewById(R.id.price_product));
        itemStore = (TextView) itemView
                .findViewById(R.id.prod_store);
        itemSpecialText = (TextView) itemView
                .findViewById(R.id.tvspecial);
         itemPriceOrig.setPaintFlags(itemPriceOrig
                .getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);                

    }

}

public DealsRecyclerAdapter(Context context, JSONObject jsonObject, int layoutId) {
    try {
        this.layoutId = layoutId;
        this.context = context;
        dealItemOnClickListener = (DealItemOnClickListener) (context);
        options = new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.load)
                .showImageForEmptyUri(R.drawable.load)
                .showImageOnFail(R.drawable.notfound)
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .considerExifParams(true)
                .resetViewBeforeLoading(true)
                .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
                .build();

        imageLoader = ImageLoader.getInstance();

        JSONArray jsonArray = jsonObject.getJSONArray(RESULTS);
        for (int i = 0; i < jsonArray.length(); i++) {
            try {
                items.add(Utils.getdealIemFromJson(jsonArray.getJSONObject(i)));

            } catch (Exception e) {
            }

        }

    } catch (Exception e) {
    }

}

public void add(DealItem item) {
    items.add(item);
}

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


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
    v.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (dealItemOnClickListener != null)
                dealItemOnClickListener.dealItemClicked(view);
        }
    });
    ViewHolder vh = new ViewHolder(v);
    return vh;
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {

    item = (DealItem) items.get(position);

    holder.itemDisc.setText("(" + (int) Math.abs(item.discount) + OFF + ")");
    holder.itemPriceOrig.setText(RS + item.originalPrice);
    holder.itemPriceOrig.setVisibility(item.priceVisiblity);
    holder.itemDisc.setVisibility(item.discountVisiblity);
    holder.itemPrice.setText(RS + item.dealPrice);
    storeName = AVAIL_FROM + "<b>" + item.store + "</b>";
    holder.itemStore.setText(Html.fromHtml(storeName));
    holder.itemName.setText(item.title);
    holder.itemSpecialText.setText(item.specialText);
    holder.itemSpecialText.setVisibility(item.specialTextVisibility);
    imageLoader.displayImage(item.imageUrl, holder.itemImage, options);
    holder.itemView.setTag(item);
}

@Override
public long getItemId(int arg0) {

    return 0;
}

public interface DealItemOnClickListener {
    void dealItemClicked(View view);
}

public void setLayoutId(int layoutId) {
    this.layoutId = layoutId;
}

}

2 个答案:

答案 0 :(得分:8)

运行时缩放和图像大小都会产生影响。 通常不鼓励运行时缩放,图像大小直接影响任何时候可以缓存多少。

我也会加入@ Alireza的问题并提出一个问题;如果您评论图像加载是否可以?

我还会将您推荐给我认为更好的第三方图片加载库,例如FrescoGlidePicasso我有很多经验并可以保证他们的效率。

最后但同样重要的是,我会邀请您查看我的一位朋友Ran Nachmany给出的会话,在那里他解释了如何使用透支,systrace和其他工具here来分析这些问题。

古德勒克。

答案 1 :(得分:3)

我仔细阅读了你的代码,似乎唯一有问题的一行就是这个

    imageLoader.displayImage(item.imageUrl, holder.itemImage, options);

我没有使用UniversalImageLoader。它是否处理单独线程中的图像加载?

通过将这些确切的图像放在资源目录中并使用imageView.setImageResource查看是否仍有问题,您可以通过任何方式简单地确定此行是否存在问题。

如果我是对的并且UniversalImageLoader让你的应用程序变慢,你可以创建一个AsyncTask并在单独的线程中运行这一行,或者使用像Picaso这样的另一个图像加载库。

造成问题的下一个候选人是图像。 300K可能会很低,但如果总结图像大小,你会得到数百万的内存使用量,这足以引起即使是最好的Android设备的问题。 (Android内存监视器在这里是一个非常有用的工具!)以及像.jpg这样的图像格式使用压缩来减小大小,这使得解压缩文件变慢。解决方案是photoshop,只需创建新照片并复制并通过现有照片并保存。大多数时候默认选项都可以!

关于无关紧要的问题最后一个想法!我看到你在适配器中处理jsonObject这不是一个好习惯。 Puting是您的活动/片段中的代码,或者更好的某些网络实用程序类会更好。

对不起,如果我不能再帮忙了。祝你好运