所以我一直在创建类似于GridView的自定义视图。当它们是应用程序内部的资源时,它会很好地加载和滚动图像,但现在我正在使用通过HTTP请求进入的图像,图像无法正确加载。
应用程序启动时:所有图像都设置为默认值(错误)
滚动浏览该单元格并立即滚动回去:图像正确加载(好)
稍后滚动回同一个单元格后:图像被设置回默认值(坏)
有没有人对可能导致此错误的原因有任何想法?我认为这是某种回收问题,但我无法解决它。
这是我的xml文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingBottom="1dip"
android:background="@color/white"
android:id="@+id/highlight_counter_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:gravity="center" >
<ImageView
android:id="@+id/catalog_image"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<View
android:id="@+id/solid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@android:color/black" />
<View
android:id="@+id/text_gradient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/solid"
android:background="@drawable/highlight_text_gradient" />
<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:padding="@dimen/highlight_text_padding"
android:ellipsize="end"
android:gravity="bottom"
android:maxLines="2"
android:textColor="@color/white"
android:textSize="@dimen/text_large" />
</RelativeLayout>
以下是我的适配器的摘录(我认为问题可能存在):
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final LayoutParams lp;
int viewType = getItemViewType(position);
ImageView img;
PulseTextView title;
Resources res = getContext().getResources();
int height = (int) res.getDimension(R.dimen.icon_main_size);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.get().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.element_item, parent, false)
LayoutParams layp = new LayoutParams(height);
convertView.setLayoutParams(layp);
}
img = ViewHolder.get(convertView,R.id.catalog_image);
title = ViewHolder.get(convertView,R.id.title);
final CatalogItem channel = getCatalogItem(position);
// find the url of the associated image then set image
String url = null;
try {
url = mCatalogHandler.getImageUrl(CatalogHandler.VALUE_ICON, channel.mPrimaryKey, 100, 100);
} catch (CatalogException e) {
e.printStackTrace();
}
if (url == null || TextUtils.isEmpty(url) || url.equals("null")) {
img.setImageBitmap(mDefaultPic);
} else {
// downloads the image to img
mImageDownloader.download(url, img, mDefaultPic, false);
}
title.setText(channel.mDomain);
img.setScaleType(ScaleType.FIT_XY);
img.setTag(RAMImageCache.KEY_URL, url);
// set the gradient behind the text
View grad = convertView.findViewById(R.id.text_gradient);
ViewUtils.setHeight(grad, height * 3 / 5);
grad.getBackground().setDither(true);
View solid = convertView.findViewById(R.id.solid);
ViewUtils.setHeight(solid, height / 5);
// set the padding based on the position on the screen
DisplayMetrics displaymetrics = new DisplayMetrics();
((Activity)getContext()).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = displaymetrics.widthPixels;
if (convertView.getRight() == width && convertView.getLeft() == 0) {
convertView.setPadding(0, 0, 0, 1);
} else if (convertView.getRight() == width) {
//convertView.setPadding(1, 0, 0, 1);
convertView.setPadding(0, 0, 1, 1);
} else if (convertView.getLeft() == 0) {
//convertView.setPadding(0, 0, 1, 1);
convertView.setPadding(1, 0, 0, 1);
}
// set the onclicklistener to jump to the next fragment
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Bundle bundle = new Bundle();
bundle.putString("channelitem", channel.getMetadata().toString());
ChannelFragment fragment = new ChannelFragment();
fragment.setArguments(bundle);
((PulseFragmentActivity)mContext.get()).openFragment(fragment);
}
});
return convertView;
}
static class ViewHolder {
ImageView img;
TextView title;
public ViewHolder(ImageView i, PulseTextView t) {
img = i;
title = t;
}
public static <T extends View> T get(View view, int id) {
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
if (viewHolder == null) {
viewHolder = new SparseArray<View>();
view.setTag(viewHolder);
}
View childView = viewHolder.get(id);
if (childView == null) {
childView = view.findViewById(id);
viewHolder.put(id, childView);
}
return (T) childView;
}
}
正确方向的任何一点都会有很大帮助!如果您还需要查看其他任何代码段,请与我们联系。
答案 0 :(得分:0)
我建议调试的一种方法是尝试使用另一个图像下载库来查明代码中是否存在错误。我使用https://github.com/koush/UrlImageViewHelper并且在重复使用单元格时效果很好,其API与您现在使用的类似
答案 1 :(得分:0)
这种行为在很大程度上取决于mImageDownloader
处理下载图像的方式和方式。
在大多数情况下,LRU Cache实现可能用于存储下载的映像,并且此缓存具有分配的最大字节值。一旦您的缓存图像超过此值,旧的位图将被丢弃,因此您看到默认图像的原因,您需要重新下载它。
我的建议是在您下载图像后,尽可能缩小图像,以便尽可能多地缓存位图。
由于内存限制,Android无法缓存所有下载的图像。