java - 我的 ListView 不断使用 LogoLoader Asynctask 刷新图像

标签 java android android-listview android-asynctask listadapter

我的 ListView 有一个自定义适配器,在 ListView 中,它为每个图像设置一个异步任务,以从后台的网络服务加载图像,然后显示它。但图像不断刷新,有时一段时间后会加载错误的图像。(第一次加载时显示正确的图像)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);
    }

}

}

最佳答案

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

holder.imageView.setImageBitmap(null);

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

关于java - 我的 ListView 不断使用 LogoLoader Asynctask 刷新图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19242931/

相关文章:

java - 如何在 scriptlet 中使用 JSTL 变量?

java - 无法在eclipse中选择Android Build Target

java - 如何使用 AES 将字符串加密为仅包含特定字符的字符串?

java - android dalvik验证错误: register1 v1 type 0,想要引用

java - 将 ForkJoinPool 与 AsyncHttpClient 一起使用 - 这有意义吗?

java - SQLiteDatabase Android 中出现 java.lang.NullPointerException 错误

android - Genymotion旧版下载

java - 将数据从互联网加载到 ListView 的最合适方法

android - 水平 ListView

android - ListView 不在自定义 ViewGroup 中刷新