简体   繁体   中英

Change an ImageView inside a ListView

I saw a code from Android Hive, and I learned how to send array JSON from the PHP script to my Android / Java code. I successfully retrieved all the details from my online database and displayed them in my desired format.

The problem is, I don't know hot to set an image's src when it is inside a ListView. Here's my code.

                ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
                JSONParser jParser = new JSONParser();
                JSONObject json = jParser.getJSONFromUrl("http://domain.com/directory/database/retrieveComments.php?placeId=" + stringPlaceId);
                try
                {
                    commentsRatingsArray = json.getJSONArray("commentsRatings");
                    for(int i = 0; i < commentsRatingsArray.length(); i++)
                    {
                        JSONObject jsonObject = commentsRatingsArray.getJSONObject(i);
                        String dbUserFullName = jsonObject.getString(TAG_FULLNAME);
                        String dbUserEmail = jsonObject.getString(TAG_EMAIL);
                        String dbComment = jsonObject.getString(TAG_COMMENT);
                        String dbRating = jsonObject.getString(TAG_RATING);
                        String dbDate = jsonObject.getString(TAG_DATE);
                        String dbTime = jsonObject.getString(TAG_TIME);

                        HashMap<String, String> map = new HashMap<String, String>();
                        map.put(TAG_FULLNAME, dbUserFullName);
                        map.put(TAG_EMAIL, dbUserEmail);
                        map.put(TAG_COMMENT, dbComment);
                        map.put(TAG_RATING, dbRating);
                        map.put(TAG_DATE, dbDate);
                        map.put(TAG_TIME, dbTime);

                        list.add(map);
                    }   
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    Toast.makeText(getBaseContext(), "Connection to the server is lost. Please check your internet connection.", Toast.LENGTH_SHORT).show();
                }

                ListAdapter adapter = new SimpleAdapter
                        (DisplayCommentsRatings.this, list, R.layout.commentrating,

                            new String[] { TAG_FULLNAME, TAG_EMAIL, TAG_COMMENT, TAG_DATE,  TAG_TIME },
                            new int[] {R.id.tvUserFullName, R.id.tvUserEmail, R.id.tvUserComment, R.id.tvDate, R.id.tvTime });

                setListAdapter(adapter);

Please help me, thanks.

For that i would suggest you to define a custom adapter for your ListView.

  1. You can create custom adapter class by extending either BaseAdapter or ArrayAdapter.
  2. override getView() method.
  3. Follow ViewHolder pattern while overiding getView() method.

Here, Ravi has written about: Android custom ListView with Images and Text .

And the best solution so far: Andoid - Lazy Load of Images in ListView

I think you will have to make your own custom adapter (extending BaseAdapter ) and update the image inside the getView method. There is a lot of tuts on Google.

Good luck =)

You can set your image with an URL pointing to the SD name of the file for example.

http://developer.android.com/reference/android/widget/SimpleAdapter.html#setViewImage(android.widget.ImageView , int)

But i think that is a lot easier to extend from BaseAdapter and pass your own Map or Array to it and then you can inflate with any image that you want, download it and set it, etc.

This is an example of one Adapter for devices :) you dont need to start with viewHolder pattern.

public class DevicesAdapter extends BaseAdapter {
private LayoutInflater inflater;
private List<Device> devices;

public DevicesAdapter(Context context, List<Device> devices) {
    inflater = LayoutInflater.from(context);
    this.devices = devices;
}

@Override
public int getCount() {
    return devices.size();
}

@Override
public Object getItem(int position) {
    return devices.get(position);
}

@Override
public long getItemId(int position) {
    return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    if (row == null) {
        row = inflater.inflate(R.layout.account_devices_row, null);
    }
    TextView description = (TextView) row.findViewById(R.id.device_text);
    description.setText(devices.get(position).getLabel());
    return row;
}

}

Regards

They are correct above. You will want to extend a BaseAdapter and overwrite the getView method. You will also want to lazy load the image since you are will be downloading them and shouldn't tie up the UI thread while this action is being performed. Below is my Lazy Load class. Simple create a new class (I call mine LazyLoadImage.java) and stick this code in it. Below are the different ways you can use the class:

To lazy load an image with a placeHolder:

new LazyLoadImage(ImageView imageView, String urlString, Bitmap placeHolder);

To lazy load an image without a placeHolder:

new LazyLoadImage(ImageView imageView, String urlString);

To manually clear the cache:

new LazyLoadImage().clearCache();

If you are targeting OS's below 12 then you will need to include "android-support-v4.jar" in the project.

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.widget.ImageView;

public class LazyLoadImage extends AsyncTask<String, Void, Bitmap> {

ImageView mDestination;

//Set up cache size and cache
private static int mCacheSize = 4 * 1024 * 1024; // 4 mb
private static LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(mCacheSize) {
    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight();
    }
};


public LazyLoadImage(ImageView destination, String urlString) {
    mDestination = destination;

    if (mCache.get(urlString) != null) {
        mDestination.setImageBitmap(mCache.get(urlString));
    }else {
        this.execute(urlString);
    }
}

public LazyLoadImage(ImageView destination, String urlString, Bitmap placeHolder) {
    mDestination = destination;

    if (mCache.get(urlString) != null) {
        mDestination.setImageBitmap(mCache.get(urlString));
    }else {
        setPlaceHolder(urlString, placeHolder);
        this.execute(urlString);
    }
}

public LazyLoadImage() {
}

private void setPlaceHolder(String urlString, Bitmap placeholder) {
    mDestination.setImageBitmap(placeholder);
}

public void clearCache() {
    mCache.evictAll();
}

@Override
protected Bitmap doInBackground(String... arg0) {

    //If the URI that is passed in arg0[0] is already in mCache then I return it without downloading it again
    if (mCache.get(arg0[0]) != null) {
        return mCache.get(arg0[0]);
    }else {

        Bitmap lazyImage = null;
        URL myFileUrl = null;          

        try {
             myFileUrl= new URL(arg0[0]);
             HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
             conn.setDoInput(true);
             conn.connect();
             InputStream is = conn.getInputStream();

             lazyImage = BitmapFactory.decodeStream(is);

             //Store the image in mCache for quick assess from anywhere in app
             synchronized (mCache) {
                if (mCache.get(arg0[0]) == null) {
                    mCache.put(arg0[0], lazyImage);
                }
             }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return lazyImage;
    }
}

@Override
protected void onCancelled(Bitmap result) {

}

@Override
protected void onPostExecute(Bitmap result) {

    /*
     * The returned image to the ImageView that was passed in on create
     *  (either from mCache or when downloaded the first time)
     */
    mDestination.setImageBitmap(result);

    super.onPostExecute(result);
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM