0

我的列表视图有一个自定义适配器,在列表视图中,它为每个图像设置一个异步任务,以从后台的 Web 服务加载图像,然后显示它。但是图像不断刷新,有时会在一段时间后加载错误的图像。(第一次加载它显示正确的图像) LogoLoader 是异步任务。

适配器类:

public class SearchResultAdapter extends ArrayAdapter<SearchResultRowItem> {

Context context;
private MainActivity main;

public SearchResultAdapter(Context context, int resourceId, List<SearchResultRowItem> items,MainActivity main) {
    super(context, resourceId, items);
    this.context = context;
    this.main = main;
}

/*private view holder class*/
private class ViewHolder {
    ImageView imageView;
    TextView txtTitle;
    TextView txtDesc;
    TextView txtAdres;
    TextView txtAfstand;
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    SearchResultRowItem rowItem = getItem(position);

    LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.listitem, null);
        holder = new ViewHolder();
        holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
        holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
        holder.txtAdres = (TextView) convertView.findViewById(R.id.adres);
        holder.txtAfstand = (TextView) convertView.findViewById(R.id.afstand);
        holder.imageView = (ImageView) convertView.findViewById(R.id.logo);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }


    holder.txtDesc.setText(Html.fromHtml(rowItem.getDesc()));
    holder.txtTitle.setText(rowItem.getTitle());
    holder.txtAdres.setText(rowItem.getAdres());
    holder.txtAfstand.setText(rowItem.getAfstand());

    if (holder.imageView != null && rowItem.hasLogo()) {
        holder.imageView.setImageResource(R.drawable.loader);
        LogoLoader logoLoader = new LogoLoader(holder.imageView, rowItem.getOrganisatieId(), 100, 100, main);
        logoLoader.execute();
    }

    convertView.setBackgroundColor(position % 2 == 0 ? Color.WHITE : Color.parseColor("#F8F8F8"));
    return convertView;
}

}

LogoLoader 类:

public class LogoLoader extends AsyncTask<Void, Void, String> {

private ImageView imageView;
private UUID OrganisationGuid;
private int maxWidth;
private int maxHeight;

private MainActivity main;

public LogoLoader(ImageView imageView, UUID OrganisationGuid, int maxHeight, int maxWidth,MainActivity main) {
    this.imageView = imageView;
    this.OrganisationGuid = OrganisationGuid;
    this.maxHeight = maxHeight;
    this.maxWidth = maxWidth;
    this.main = main;
}

@Override
protected String doInBackground(Void... params) {
    WebserviceAdapter task = new WebserviceAdapter(
            "api/Logo/GetLogos?ids="+OrganisationGuid.toString()+
            "&maxWidth="+Integer.toString(maxWidth)+
            "&maxHeight="+Integer.toString(maxHeight));
    return task.result;
}

@Override
protected void onPostExecute(String result){
    try {
        JSONObject json = new JSONObject(result);

        JSONArray jsonArray = json.getJSONArray("Results");
        JSONObject imageObject = jsonArray.getJSONObject(0);

        byte[] imageData = Base64.decode( imageObject.getString("Data").getBytes(), Base64.DEFAULT);
        Drawable logoDrawable = null;
        if (imageData != null) {
            Bitmap logoBitmap = BitmapFactory.decodeByteArray(imageData, 0,
                    imageData.length);
            logoDrawable = new BitmapDrawable(main.getResources(), logoBitmap);
        }
        imageView.setImageDrawable(logoDrawable);
    } catch (JSONException e) {
        imageView.setImageDrawable(null);
    }

}

}

4

2 回答 2

1

重复加载是由于 listview 的 getView 方法被定期调用多次,而加载错误的图像是由于 resuing view 的特性。ListView 尝试重用项目视图以节省内存并提高效率。第一个问题的解决方案是只加载一次图像并将其保存在某处(如果图像是缩略图,则在内存中,如果图像较大,则在 SDCard 上)。第二个问题的解决方案是使用

holder.imageView.setImageBitmap(null);

之前if (holder.imageView != null && rowItem.hasLogo()) {,这样每当视图被渲染时,它就不会加载以前的图像。我希望你明白我的意思。您还可以使用通用图像加载器库来加载图像。我用过它,它就像一个魅力。

于 2013-10-08T10:16:43.953 回答
0

我可以推荐一种不同的加载图像的方法,它就像一个魅力:Android Query。

您可以从这里下载该 jar 文件:http ://code.google.com/p/android-query/downloads/list

AQuery androidAQuery=new AQuery(this);

举个例子:

androidAQuery.id(YOUR IMAGEVIEW).image(YOUR IMAGE TO LOAD, true, true, getDeviceWidth(), ANY DEFAULT IMAGE YOU WANT TO SHOW);

它非常快速和准确,使用它您可以在加载时找到更多功能,例如动画;如果需要,获取位图;等等

于 2013-10-08T08:43:25.670 回答