如何从自定义适配器动态设置列表视图的imageView源?

时间:2013-11-16 17:19:29

标签: java android listview android-arrayadapter

我正在尝试根据自定义ArrayAdapter中的字符串设置imageView源,但我无法让它工作。我知道对象rec_gift正确通过,而icon_string变量得到正确的名称,但是setImageResource调用不起作用。

public class MySimpleArrayAdapter extends ArrayAdapter<Gift> {
  private final Context context;
  private List<Gift> giftz2;

  public MySimpleArrayAdapter(Context context, List<Gift> giftx) {
        super(context, R.layout.listview_rowlayout, giftx);
    this.context = context;
        this.giftz2 = giftx;
      }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.listview_rowlayout, parent, false);

    ImageView iconz = (ImageView) rowView.findViewById(R.id.icon);

    Gift rec_gift = (Gift) getItem(position);

    String icon_string = "R.drawable." + rec_gift.photo_key;

    iconz.setImageResource(getImageId(icon_string));

    return rowView;
  }

  public int getImageId(String imageName) {
        return context.getResources().getIdentifier("drawable/" + imageName, null, context.getPackageName());
    }
} 

在上面的代码中,我想基于icon_string变量设置imageView,因此listView中的每一行都将获得正确的图像,但它根本没有进行任何更改。

2 个答案:

答案 0 :(得分:3)

实现自定义适配器的getItem方法:

@Override
public Gift getItem(int position) {
    if(this.giftz2 != null) {
        this.giftz2.get(position);
    } else {
        return null;
    }
}

并改变这一点:

public int getImageId(String imageName) {
    return context.getResources().getIdentifier("drawable/" + imageName, null, context.getPackageName());
}

对此:

public int getImageId(String imageName) {
    return context.getResources().getIdentifier(imageName, "drawable", context.getPackageName());
}

并致电方法:

String icon_string = String.valueOf(rec_gift.photo_key);
iconz.setImageResource(getImageId(icon_string));

BTW:尝试在适配器getView方法中重用您的视图。如果继续使用实现,则会出现内存错误。

答案 1 :(得分:1)

如果您尝试从Web服务下载图像并在imageview中设置该图像,则可以使用图像加载器

将此行放在您要显示图像的适配器中并传递参数

ImageLoader_class(image_url, image_view , progressbar);

// new创建一个名为ImageLoader_class的类,并将此代码粘贴到该

    import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Stack;


import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;




public class ImageLoader_class{
    private static MemoryCache memoryCache = new MemoryCache();
    // private static FileCache fileCache;
    private static boolean isImageLoaderClass = true;
    private static ImageLoader_circle_img imageLoader = null;
    final static int stub_id = R.drawable.ic_launcher;
    private static Bitmap defaultBitmap = null;
    private static Context mContext;

    /**
     * This is constructor of ImageLoader Class make the background thread low
     * priority. This way it will not affect the UI performance *
     * 
     * @param mContext
     *            application context
     */
    private ImageLoader_circle_img(Context context) {
        mContext = context;

        photoLoaderThread.setPriority(Thread.NORM_PRIORITY - 1);

        // fileCache = new FileCache(mContext);
    }

    /**
     * This Method is used to implement singleton concept in this class
     * 
     * @param context
     *            application context
     * @return Class object of this class
     */
    public static ImageLoader_circle_img getInstanceImageLoader(Context context) {
        if (isImageLoaderClass) {
            isImageLoaderClass = false;
            imageLoader = new ImageLoader_circle_img(context);
            return imageLoader;
        }
        return imageLoader;
    }

    /**
     * This method is used to set image in image view
     * 
     * @param url
     *            from this URL, image will be down-load
     * @param imageView
     *            in this view set the image bitmap
     * @param progressBar
     *            which is show when image is displaying
     */

    @SuppressWarnings("deprecation")
    public static void DisplayImage(String url, ImageView imageView,
            ProgressBar progressBar) {

        if (url == null || url.equals("")) {
            imageView.setVisibility(View.VISIBLE);
            // imageView.setImageBitmap(getDefaultBitmap());
            imageView.setBackgroundDrawable(new BitmapDrawable(
                    getDefaultBitmap()));
            progressBar.setVisibility(View.INVISIBLE);


        } else if (memoryCache.get(url) != null) {
            imageView.setVisibility(View.VISIBLE);
            // imageView.setImageBitmap(memoryCache.get(url));
            imageView.setBackgroundDrawable(new BitmapDrawable(memoryCache
                    .get(url)));
            progressBar.setVisibility(View.INVISIBLE);

        } else {
            queuePhoto(url, imageView, progressBar);
            System.out.println("url"+url);
        }
    }
    public static Bitmap getRoundedShape(Bitmap scaleBitmapImage) {
        // TODO Auto-generated method stub
        int targetWidth = 100;
        int targetHeight = 100;
        Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,
                Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(targetBitmap);
        Path path = new Path();
        path.addCircle(((float) targetWidth - 1) / 2,
                ((float) targetHeight - 1) / 2,
                (Math.min(((float) targetWidth), ((float) targetHeight)) / 2),
                Path.Direction.CCW);

        canvas.clipPath(path);
        Bitmap sourceBitmap = scaleBitmapImage;
        canvas.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth(),
                sourceBitmap.getHeight()), new Rect(0, 0, targetWidth,
                targetHeight), null);
        return targetBitmap;
    }
    /**
     * this method is used to get default bitmap if image url is null
     * 
     * @return bitmap
     */

    private static Bitmap getDefaultBitmap() {
        try {
            defaultBitmap = BitmapFactory.decodeResource(mContext
                    .getResources(), stub_id);
            int width = defaultBitmap.getWidth();
            int height = defaultBitmap.getHeight();
            return Bitmap.createScaledBitmap(defaultBitmap, width / 4,
                    height / 4, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * If bitmap is not downloaded then add in queue
     * 
     * @param url
     *            from this URL, image will be down-load
     * @param imageView
     *            in this view set the image bitmap
     * @param progressBar
     *            which is show when image is displaying
     */
    private static void queuePhoto(String url, ImageView imageView,
            ProgressBar progressBar) {
        photosQueue.Clean(imageView);
        PhotoToLoad p = new PhotoToLoad(url, imageView, progressBar);
        synchronized (photosQueue.photosToLoad) {
            photosQueue.photosToLoad.push(p);
            photosQueue.photosToLoad.notifyAll();
        }

        // start thread if it's not started yet
        if (photoLoaderThread.getState() == Thread.State.NEW)
            photoLoaderThread.start();
    }

    /**
     * this method is used to download bitmap
     * 
     * @param url
     *            from this URL, image will be down-load
     * @return bitmap
     */
    private static Bitmap getBitmap(String url) {

        URL myFileUrl = null;
        Bitmap bmImg = null;
        try {
            myFileUrl = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        try {
            HttpURLConnection conn = (HttpURLConnection) myFileUrl
                    .openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bmImg = BitmapFactory.decodeStream(is);

        } catch (IOException e) {
            e.printStackTrace();
        }
        if (bmImg != null)


        System.out.println(" bmImg.getWidth()"+ bmImg.getWidth());

        if(bmImg.getWidth()>300)
        {
            bmImg = Bitmap.createScaledBitmap(bmImg, bmImg.getWidth(),
                    bmImg.getHeight() , true);

        //  bmImg = Bitmap.createScaledBitmap(bmImg, bmImg.getWidth() / 4,
            //      bmImg.getHeight() / 4, true);
            System.out.println("IF STAT");
        }
        else
        {
            bmImg = Bitmap.createScaledBitmap(bmImg, 55,
                    55, true);

        }
        //Bitmap bt = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
        //imageView.setImageBitmap(getRoundedShape(bmImg));
        //if the image needed in round shape
        //return getRoundedShape(bmImg);
        return bmImg;
    }

    /**
     * This class is used to manage url, imageview and progressBar
     */
    private static class PhotoToLoad {
        public String url;
        public ImageView imageView;
        public ProgressBar view;

        public PhotoToLoad(String u, ImageView i, ProgressBar v) {
            url = u;
            imageView = i;
            view = v;
        }
    }

    private static PhotosQueue photosQueue = new PhotosQueue();

    private static void stopThread() {
        photoLoaderThread.interrupt();
    }

    /**
     * this class is used to store list of photoes
     */
    private static class PhotosQueue {
        private Stack<PhotoToLoad> photosToLoad = new Stack<PhotoToLoad>();


        // removes all instances of this ImageView
        public void Clean(ImageView image) {

            for (int j = 0; j < photosToLoad.size();) {

                if (photosToLoad.get(j).imageView == image)

                    photosToLoad.remove(j);
                else
                    ++j;
            }
        }
    }

    /**
     * This thread is used to set photoes in imageView
     */
    private static class PhotosLoader extends Thread {
        @Override
        public void run() {
            try {
                while (true) {
                    // thread waits until there are any images to load in the
                    // queue
                    if (photosQueue.photosToLoad.size() == 0) {
                        synchronized (photosQueue.photosToLoad) {
                            photosQueue.photosToLoad.wait();
                        }
                    }
                    if (photosQueue.photosToLoad.size() != 0) {
                        PhotoToLoad photoToLoad;
                        synchronized (photosQueue.photosToLoad) {
                            photoToLoad = photosQueue.photosToLoad.pop();
                        }
                        Bitmap bmp;
                        try {
                            bmp = getBitmap(photoToLoad.url);
                            memoryCache.put(photoToLoad.url, bmp);
                            if (((String) photoToLoad.imageView.getTag()).equals(photoToLoad.url)) {
                                BitmapDisplayer bd = new BitmapDisplayer(bmp,
                                        photoToLoad.imageView, photoToLoad.view);
                                Activity a = (Activity) photoToLoad.imageView
                                        .getContext();
                                a.runOnUiThread(bd);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    if (Thread.interrupted())
                        break;
                }
            } catch (InterruptedException e) {
                // allow thread to exit
            }
        }
    }

    private static PhotosLoader photoLoaderThread = new PhotosLoader();

    /**
     * Used to display bitmap in the UI thread
     */
    private static class BitmapDisplayer implements Runnable {
        Bitmap bitmap;
        ImageView imageView;
        ProgressBar view;

        public BitmapDisplayer(Bitmap b, ImageView i, ProgressBar v) {
            bitmap = b;
            imageView = i;
            view = v;
        }

        @SuppressWarnings("deprecation")
        public void run() {
            if (bitmap != null) {
                imageView.setVisibility(View.VISIBLE);
                // imageView.setImageBitmap(bitmap);
                imageView.setBackgroundDrawable(new BitmapDrawable(bitmap));

                view.setVisibility(View.INVISIBLE);
            }
        }
    }

    /**
     * this function is used to clear all stored data
     */
    public static void clearCache() {
        stopThread();

        // clear memory cache
        memoryCache.clear();

        // clear SD cache
        /*
         * if (fileCache != null) { fileCache.clear(); }
         */
    }
}