0

所以我一直在创建一个类似于 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;
    }
}

朝着正确方向的任何一点都会有很大帮助!让我知道您是否需要查看其他代码片段。

4

2 回答 2

0

行为很大程度上取决于您mImageDownloader处理下载图像的内容和方式。

在大多数情况下,LRU 缓存实现可能用于存储您下载的图像,并且此缓存具有分配的最大字节值。一旦您的缓存图像超过此值,旧的位图将被丢弃,因此您会看到默认图像并且您需要重新下载它。

我的建议是在你下载了图片之后,尽可能地缩小它,这样你就可以缓存尽可能多的位图。

由于内存限制,Android 无法缓存所有下载的图像。

于 2013-06-10T03:26:23.843 回答
0

我建议调试的一种方法是尝试另一个图像下载库,以确定错误是否在您的代码中。我用了https://github.com/koush/UrlImageViewHelper,在重用cell的时候效果很好,它的API和你现在用的差不多

于 2013-06-10T02:12:38.650 回答