【问题标题】:Loading images in a Listview properly正确加载列表视图中的图像
【发布时间】:2013-08-26 11:18:21
【问题描述】:

我正在使用 Universal Image Loader 库在我的列表视图中加载图像,它会加载图像,但我注意到,如果您第一次快速滚动,您会看到在正确图像之前首先加载了错误的图像。

我怎样才能阻止这种影响。下面是我的整个班级。

public MyListAdapter(Context context, List<VenueDetails> m_venue_details) {
    super(context, R.layout.venue_list_row, m_venue_details);

    this.context = context;
    this.venue_details = new ArrayList<VenueDetails>();
    this.venue_details = m_venue_details;
    df = new DecimalFormat("#.##");
}

@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
public View getView(int position, View v, ViewGroup parent) {

    final ViewHolder holder;
    final VenueDetails vD =  venue_details.get(position);   

    if (inflater == null) {
        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    if (v == null) {
        v = inflater.inflate(R.layout.venue_list_row, parent,false);
        holder = new ViewHolder();
        holder.venue_name = (TextView) v.findViewById(R.id.venue_name);
        holder.venue_dist = (TextView) v.findViewById(R.id.venue_dist);
        holder.curr_loc = (TextView) v.findViewById(R.id.curr_loc);
        holder.ll = (FrameLayout) v.findViewById(R.id.venue_frame);
        holder.pett_btn = (Button) v.findViewById(R.id.venue_pett);
        holder.img = (ImageView) v.findViewById(R.id.venue_logo);

        v.setTag(holder);

    }else{
        holder = (ViewHolder) v.getTag();
    }

    holder.img.setTag(vD.logo);

    if(vD.list_img == null){
        myAppObj.getImageLoader().loadImage(holder.img.getTag().toString(), new ImageLoadingListener() {

            @Override
            public void onLoadingStarted(String imageUri, View view) {
                holder.img.setBackgroundResource(R.drawable.placeholder_venue);
            }

            @Override
            public void onLoadingFailed(String imageUri, View view,
                    FailReason failReason) {    
                holder.img.setBackgroundResource(R.drawable.placeholder_pin);                   
            }

            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                holder.img.setBackgroundDrawable(new BitmapDrawable(loadedImage));
                if(vD.list_img == null){
                    vD.list_img = new BitmapDrawable(loadedImage);
                }
            }

            @Override
            public void onLoadingCancelled(String imageUri, View view) {
                holder.img.setBackgroundResource(R.drawable.placeholder_venue);
            }
        });
    }else{
        holder.img.setBackgroundDrawable(vD.list_img);
    }

    if(vD != null){         

        holder.venue_name.setText(vD.venueName.toUpperCase());
        venue_details.get(position).venue_distance = Double.parseDouble(df.format(Utils.distance(myAppObj.getMyLatitude(), myAppObj.getMyLongitude(), vD.latitude, vD.longitude, 'K') * 0.000621371192));
        holder.venue_dist.setText(df.format(vD.venue_distance)+" Miles");


        holder.venue_curr_loc.setText(my_address.toUpperCase());

        if (vD.petted == 1) {

            holder.pett_btn.setVisibility(View.VISIBLE);
            holder.ll.setVisibility(View.VISIBLE);

            holder.pett_btn.setOnClickListener(new OnClickListener() {
                @Override               
                public void onClick(View v) {                   
                    if(dialog_Callback!=null)
                        dialog_Callback.onDialogCalled(0, vD.id);
                }
            });

        } else {

            holder.pett_btn.setVisibility(View.GONE);
            holder.ll.setVisibility(View.GONE);
        }           
    }

    return v;
}

@Override
public boolean isEnabled(int position) {
    if (venue_details.get(position).petted == 1) {
        return false;
    } else {
        return true;
    }
}

static class ViewHolder{
    TextView venue_name;
    TextView venue_dist;
    TextView venue_curr_loc;
    FrameLayout ll;
    Button pett_btn;
    ImageView img;
}

【问题讨论】:

  • 在你的 DisplayImageOptions 上放这个 .resetViewBeforeLoading(true)

标签: android android-listview android-arrayadapter android-adapter universal-image-loader


【解决方案1】:

这是因为它的回收视图,所以 getView 中的第二个参数(View v)已经保存了前一个列表项的内容。因此,您需要清除该 imageView,因为它不会立即更改(由于正在下载图像)。

将您的代码更改为这样的代码应该可以工作

if (v == null) { 

...

}else{
    holder = (ViewHolder) v.getTag();
    holder.img.setImageResource(0);
    holder.img.setBackgroundDrawable(0);
}

【讨论】:

  • 对它没有太大的改变
  • 对我来说也没有任何改变。
【解决方案2】:

最好的解决方案是使用Picasso 非常容易使用和更好的性能

【讨论】:

    【解决方案3】:

    我之前遇到过这个问题,我意识到: 第一的: 1- 通用图像加载器库中的 AsyncTask 类应该有一个 WeakReference 用于图像将被加载的 imageView。

    2- 在滚动并显示带有图像的行时,其 AsyncTask 仍在获取图像,您必须确保不会为同一图像启动其他 AsyncTask。

    经过漫长的搜索之旅以解决您的确切问题,我找到了另一个课程,您可以对其进行自定义以满足您的要求。

    package com.nweave.utils;
    
    import java.io.IOException;
    import java.lang.ref.WeakReference;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.security.KeyStore;
    
    import org.apache.http.HttpResponse;
    import org.apache.http.HttpVersion;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.conn.ClientConnectionManager;
    import org.apache.http.conn.scheme.PlainSocketFactory;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.scheme.SchemeRegistry;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
    import org.apache.http.params.BasicHttpParams;
    import org.apache.http.params.HttpParams;
    import org.apache.http.params.HttpProtocolParams;
    import org.apache.http.protocol.HTTP;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.drawable.ColorDrawable;
    import android.graphics.drawable.Drawable;
    import android.os.AsyncTask;
    import android.util.Log;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.ProgressBar;
    
    import com.nweave.view.ProductArrayAdapter;
    
    public class ImageDownloader {
        private ProductArrayAdapter productArrayAdapter;
    
        public ImageDownloader(ProductArrayAdapter productArrayAdapter) {
            this.productArrayAdapter = productArrayAdapter;
        }
    
        public void download(String name, String url, ImageView imageView,
                ProgressBar progressBar) {
            if (cancelPotentialDownload(url, imageView)) {
                BitmapDownloaderTask bitmapDownloaderTask = new BitmapDownloaderTask(
                        name, imageView, progressBar);
                DownloadedDrawable downloadedDrawable = new DownloadedDrawable(
                        bitmapDownloaderTask);
                imageView.setImageDrawable(downloadedDrawable);
                bitmapDownloaderTask.execute(url);
            }
        }
    
        private class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
            String url;
            private final WeakReference<ImageView> imageViewReference;
            private final String productName;
            private final ProgressBar progressbar;
    
            public BitmapDownloaderTask(String name, ImageView imageView,
                    ProgressBar progressBar) {
                imageViewReference = new WeakReference<ImageView>(imageView);
                productName = name;
                progressbar = progressBar;
            }
    
            @Override
            protected Bitmap doInBackground(String... params) {
                HttpResponse response = null;
                HttpClient httpsClient = getHttpsClient();
                HttpGet httpGet = new HttpGet();
                try {
                    httpGet.setURI(new URI(params[0]));
    
                    response = httpsClient.execute(httpGet);
                    Bitmap currentBitMap = BitmapFactory.decodeStream(response
                            .getEntity().getContent());
                    productArrayAdapter.cacheImages.saveImages(productName,
                            currentBitMap);
                    return currentBitMap;
                } catch (URISyntaxException e) {
                    Log.e(ImageDownloader.class.getSimpleName() + ":doInBackground",
                            e.getMessage());
                } catch (ClientProtocolException e) {
                    Log.e(ImageDownloader.class.getSimpleName() + ":doInBackground",
                            e.getMessage());
                } catch (IOException e) {
                    Log.e(ImageDownloader.class.getSimpleName() + ":doInBackground",
                            e.getMessage());
                }
                return null;
            }
    
            @Override
            protected void onPostExecute(Bitmap result) {
                if (isCancelled()) {
                    result = null;
                }
                if (imageViewReference != null) {
                    ImageView imageView = imageViewReference.get();
                    BitmapDownloaderTask bitmapDownloaderTask = ImageDownloader
                            .getBitmapDownloaderTask(imageView);
                    if (this == bitmapDownloaderTask) {
                        imageView.setImageBitmap(result);
                        imageView.setVisibility(View.VISIBLE);
                        progressbar.setVisibility(View.INVISIBLE);
                    }
                }
            }
        }
    
        private static class DownloadedDrawable extends ColorDrawable {
            private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;
    
            public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
                bitmapDownloaderTaskReference = new WeakReference<BitmapDownloaderTask>(
                        bitmapDownloaderTask);
            }
    
            public BitmapDownloaderTask getBitmapDownloaderTask() {
                return bitmapDownloaderTaskReference.get();
            }
        }
    
        private static boolean cancelPotentialDownload(String url,
                ImageView imageView) {
            BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
            if (bitmapDownloaderTask != null) {
                String bitmapUrl = bitmapDownloaderTask.url;
                if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
                    bitmapDownloaderTask.cancel(true);
                } else {
                    return false;
                }
            }
            return true;
        }
    
        private static BitmapDownloaderTask getBitmapDownloaderTask(
                ImageView imageView) {
            if (imageView != null) {
                Drawable drawable = imageView.getDrawable();
                if (drawable instanceof DownloadedDrawable) {
                    DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable;
                    return downloadedDrawable.getBitmapDownloaderTask();
                }
            }
            return null;
        }
    
        private static HttpClient getHttpsClient() {
            try {
                KeyStore trustStore = KeyStore.getInstance(KeyStore
                        .getDefaultType());
                trustStore.load(null, null);
                SSLSocketFactory sslSocketFactory = new MySSLSocketFactory(
                        trustStore);
                sslSocketFactory
                        .setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
                HttpParams params = new BasicHttpParams();
                HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
                HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
                SchemeRegistry registry = new SchemeRegistry();
                registry.register(new Scheme("http", PlainSocketFactory
                        .getSocketFactory(), 80));
                registry.register(new Scheme("https", sslSocketFactory, 443));
                ClientConnectionManager ccm = new ThreadSafeClientConnManager(
                        params, registry);
                return new DefaultHttpClient(ccm, params);
            } catch (Exception e) {
                Log.e(ImageDownloader.class.getSimpleName() + ":getHttpsClient",
                        e.getMessage());
                return new DefaultHttpClient();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-25
      • 2023-03-07
      • 2011-04-07
      相关资源
      最近更新 更多