7

我从 JSON 数组获取数据,我可以在 textviews 中显示文本,但在显示图像时遇到问题。

这是主要活动:

public class test extends ListActivity {

// url to make request
private static String url = "http://test/json.php";

// JSON Node names
private static final String CONTACTS = "contacts";
private static final String NAME = "name";
private static final String IMAGE = "image";

// contacts JSONArray
JSONArray contacts = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Hashmap for ListView
    ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();

    // Creating JSON Parser instance
    JSONParser jParser = new JSONParser();

    // getting JSON string from URL
    JSONObject json = jParser.getJSONFromUrl(url);

    try {
        // Getting Array of Contacts
        contacts = json.getJSONArray(CONTACTS);

        // looping through All Contacts
        for(int i = 0; i < contacts.length(); i++){
            JSONObject c = contacts.getJSONObject(i);

            // Storing each json item in variable
            String name = c.getString(NAME);
            String image = c.getString(IMAGE);

            // creating new HashMap
            HashMap<String, String> map = new HashMap<String, String>();

            // adding each child node to HashMap key => value
            map.put(NAME, name);
            map.put(IMAGE, image);

            // adding HashList to ArrayList
            contactList.add(map);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

    testAdapter adapter =  new testAdapter(
            test.this, contactList,
            R.layout.list_item, new String[] {},
            new int[] {});
    // updating listview
    setListAdapter(adapter);

}

这是我的适配器类:

public class testAdapter extends SimpleAdapter {

    private Context mContext;
    public ImageLoader imageLoader;
    public LayoutInflater inflater=null;
    public testAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
        super(context, data, resource, from, to);
        mContext = context;
        inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader=new ImageLoader(mContext.getApplicationContext());
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;
        if(convertView==null)
            vi = inflater.inflate(R.layout.list_item, null);

        HashMap<String, Object> data = (HashMap<String, Object>) getItem(position);
        TextView text = (TextView)vi.findViewById(R.id.name);
        String name = (String) data.get(NAME);
        text.setText(name);
        ImageView image=(ImageView)vi.findViewById(R.id.imageView1);
        imageLoader.DisplayImage(IMAGE, (Activity)mContext, image);
        return vi;
    }
}
}

这是imageLoader:

public class ImageLoader {

MemoryCache memoryCache=new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());

public ImageLoader(Context context){

    photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);

    fileCache=new FileCache(context);
}

final int stub_id=R.drawable.ic_launcher;
public void DisplayImage(String url, Activity activity, ImageView imageView)
{
    imageViews.put(imageView, url);
    Bitmap bitmap=memoryCache.get(url);
    if(bitmap!=null)
        imageView.setImageBitmap(bitmap);
    else
    {
        queuePhoto(url, activity, imageView);
        imageView.setImageResource(stub_id);
    }    
}

private void queuePhoto(String url, Activity activity, ImageView imageView)
{

    photosQueue.Clean(imageView);
    PhotoToLoad p=new PhotoToLoad(url, imageView);
    synchronized(photosQueue.photosToLoad){
        photosQueue.photosToLoad.push(p);
        photosQueue.photosToLoad.notifyAll();
    }


    if(photoLoaderThread.getState()==Thread.State.NEW)
        photoLoaderThread.start();
}

private Bitmap getBitmap(String url) 
{
    File f=fileCache.getFile(url);


    Bitmap b = decodeFile(f);
    if(b!=null)
        return b;


    try {
        Bitmap bitmap=null;
        URL imageUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);
        InputStream is=conn.getInputStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;
    } catch (Exception ex){
        ex.printStackTrace();
        return null;
    }
}


private Bitmap decodeFile(File f){
    try {

        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);


        final int REQUIRED_SIZE=70;
        int width_tmp=o.outWidth, height_tmp=o.outHeight;
        int scale=1;
        while(true){
            if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                break;
            width_tmp/=2;
            height_tmp/=2;
            scale*=2;
        }


        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}


private class PhotoToLoad
{
    public String url;
    public ImageView imageView;
    public PhotoToLoad(String u, ImageView i){
        url=u; 
        imageView=i;
    }
}

PhotosQueue photosQueue=new PhotosQueue();

public void stopThread()
{
    photoLoaderThread.interrupt();
}


class PhotosQueue
{
    private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>();


    public void Clean(ImageView image)
    {
        for(int j=0 ;j<photosToLoad.size();){
            if(photosToLoad.get(j).imageView==image)
                photosToLoad.remove(j);
            else
                ++j;
        }
    }
}

class PhotosLoader extends Thread {
    public void run() {
        try {
            while(true)
            {

                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=getBitmap(photoToLoad.url);
                    memoryCache.put(photoToLoad.url, bmp);
                    String tag=imageViews.get(photoToLoad.imageView);
                    if(tag!=null && tag.equals(photoToLoad.url)){
                        BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView);
                        Activity a=(Activity)photoToLoad.imageView.getContext();
                        a.runOnUiThread(bd);
                    }
                }
                if(Thread.interrupted())
                    break;
            }
        } catch (InterruptedException e) {

        }
    }
}

PhotosLoader photoLoaderThread=new PhotosLoader();


class BitmapDisplayer implements Runnable
{
    Bitmap bitmap;
    ImageView imageView;
    public BitmapDisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;}
    public void run()
    {
        if(bitmap!=null)
            imageView.setImageBitmap(bitmap);
        else
            imageView.setImageResource(stub_id);
    }
}

public void clearCache() {
    memoryCache.clear();
    fileCache.clear();
}

}

非常感谢您的帮助。

4

3 回答 3

3

问题已解决,来自图像的 URL 有“& amp;” 里面是不明白的。

于 2012-09-19T13:38:02.770 回答
3

现在你可以使用 Picasso 而不是编写自己的自定义图像加载器。否则,您的代码帮助很大。多谢兄弟。

这是我的适配器,将您的代码与毕加索一起使用。

public class CustomList extends SimpleAdapter {

private Context mContext;
public LayoutInflater inflater=null;
public CustomList(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
    super(context, data, resource, from, to);
    mContext = context;
    inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View vi=convertView;
    if(convertView==null)
        vi = inflater.inflate(R.layout.list_view_row, null);

    HashMap<String, Object> data = (HashMap<String, Object>) getItem(position);
    TextView text = (TextView)vi.findViewById(R.id.name);
    String name = (String) data.get("name");
    text.setText(name);
    ImageView image=(ImageView)vi.findViewById(R.id.img);
    String image_url = (String) data.get("image_url");
    Picasso.with(mContext).load(image_url).into(image);
    return vi;
  }
}
于 2015-06-25T12:45:00.130 回答
-1

Picasso的解决方案效果很好,只需记住更改您在原始类的“放置”中发送的参数!

为了导入 Picasso,将其添加到依赖项中

compile group:'com.squareup.picasso', name:'picasso', version:'2.5.2'

在 build.gradle(app) 然后 View-->Tools Windows --> Gradle然后按刷新按钮

于 2015-12-11T05:51:49.390 回答