我正在使用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;
}
}
答案 0 :(得分:8)
运行时缩放和图像大小都会产生影响。 通常不鼓励运行时缩放,图像大小直接影响任何时候可以缓存多少。
我也会加入@ Alireza的问题并提出一个问题;如果您评论图像加载是否可以?
我还会将您推荐给我认为更好的第三方图片加载库,例如Fresco,Glide和Picasso我有很多经验并可以保证他们的效率。
最后但同样重要的是,我会邀请您查看我的一位朋友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是您的活动/片段中的代码,或者更好的某些网络实用程序类会更好。
对不起,如果我不能再帮忙了。祝你好运