RecyclerView滑动卡顿问题

4
我正在使用Recyclerview Gridlayout,但在滚动时会出现延迟。
由于我正在使用RecyclerView.Adapter ViewHolder,因此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;
}

}


1
请放置您的代码!您提供的信息不足以得到答案。谢谢。 - Alireza Ahmadi
已添加代码,请查看。谢谢。 - amodkanthe
2个回答

8

运行时缩放和图像大小都会产生影响。通常不建议使用运行时缩放,图像大小直接影响可以同时缓存多少内容。

我也想参加@Alireza的问题,并提出一个问题:如果注释掉图像加载,是否可以?

我还想向您推荐我认为更好的第三方图像加载库,例如Fresco, GlidePicasso,我对它们的效率可以保证,因为我有很多经验。

最后但并非最不重要的是,我邀请您观看我的朋友Ran Nachmany的一次演讲,他解释了如何使用过度绘制、系统跟踪和其他工具分析这些问题here

祝你好运。


嗨,感谢您的帮助。我尝试了Picasso,但由于它不提供文件缓存,导致内存不足,所以我转向了通用图像加载器。我将尝试Fresco和Glide,并告诉您结果。感谢邀请我参加这个会议,我一直在寻找这样的机会。 - amodkanthe
不用客气,随时可以接受我的答案 :) - Royi Benyossef

3
我仔细阅读了你的代码,似乎唯一有问题的一行是这个:
    imageLoader.displayImage(item.imageUrl, holder.itemImage, options);

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

无论如何,您可以通过将这些确切的图像放入资源目录并使用imageView.setImageResource来确认此行是否存在问题,以查看您是否仍然存在问题。

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

下一个可能引起问题的候选项是图像。300K可能很低,但如果您将图像大小相加,您将获得足以在最佳Android设备上引起问题的内存使用量(Android内存监视器在这里真的非常有用!)。还有一些图像格式,如.jpg,使用压缩来减小文件大小,这使得解压缩文件变得更慢。解决方法是使用Photoshop,只需创建新照片并复制粘贴现有照片并保存。默认选项大多数情况下都可以!

关于无关的事情,最后一个想法!我看到您在适配器中处理jsonObject,这不是一个好的实践。将代码放在活动/片段中或更好地放在某个网络实用程序类中会更好。

如果我不能提供更多帮助,很抱歉。祝您好运


感谢您的帮助,我一定会实施您建议的更改。 - amodkanthe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接