Kæmpe Klunker
Kæmpe Klunker

Reputation: 865

Bitmaps added to ArrayList in wrong order

I'm having an article in my database, which has an image, a title and a price. I add the title and price to each of their arrays and they are in the correct order so the price matches the title. But when I load the image, I decode it like this:

    private Bitmap decodeFile(byte[] b) {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(b, 0, b.length, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE=200;

        // Find the correct scale value. It should be the power of 2.
        int scale = 1;
        while(o.outWidth / scale / 2 >= REQUIRED_SIZE && 
              o.outHeight / scale / 2 >= REQUIRED_SIZE) {
            scale *= 2;
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeByteArray(b, 0, b.length, o2);
    }

After the decoding is done, I add it to the image ArrayList like this:

imageList.add(bmp);

But then the price and title of the image could e.g. be at index 0 in the price and title ArrayLists, but the image might decode slower than another image, so how do i get the image to be added at index 0 as well? Here is my total code of loading and adding:

    private void loadData(){
        ParseQuery<ParseObject> query = ParseQuery.getQuery("Items");
        query.setLimit(20);
        query.findInBackground(new FindCallback<ParseObject>() {
            public void done(List<ParseObject> itemList, ParseException e) {
                if (e == null) {
                    Log.d("Parse", "Retrieved " + itemList.size() + " items");
                    itemsLoaded = itemList.size();
                    for (int i = 0; i < itemList.size(); i++){
                        pricesList.add(itemList.get(i).getInt("price"));
                        titlesList.add(itemList.get(i).getString("title"));
                        Log.d("Parse", "objectID = " + itemList.get(i).getObjectId());
                    }                       
                } else {
                    Log.d("Parse", "Error: " + e.getMessage());
                }
                for (int j = 0; j < titles.size(); j++){
                    ParseQuery<ParseObject> query2 = ParseQuery.getQuery("Images");
                    query2.whereEqualTo("imageId", itemList.get(j).getObjectId());
                    query2.findInBackground(new FindCallback<ParseObject>() {
                        public void done(List<ParseObject> picList, ParseException e) {
                            if (picList.size() != 0){
                            ParseFile pFile = (ParseFile) picList.get(0).get("image");

                            pFile.getDataInBackground(new GetDataCallback() {
                                public void done(byte[] data, ParseException e) {
                                    if (e == null) {
                                        Log.d("Parse", "We've got data in data.");
                                        Bitmap bmp = decodeFile(data);
                                        imageList.add(bmp);                                         
                                        if (imageList.size() == titles.size())
                                            updateGridView();   
                                    } else {
                                        Log.d("test", "There was a problem downloading the data.");
                                    }
                                }                                   
                            });
                            }
                            Log.d("Parse", "Downloaded images = " + picList.size());
                        }
                    }); 
                }
            }

        });
    }

Upvotes: 3

Views: 135

Answers (3)

Timo
Timo

Reputation: 2242

As I commented: I would use a Map, where you can define a key for each value. The key could be the unique product number. If you use this strategy for all separate attributes, you are independent of timing issues in the different loading procedures.

The techniques described in the other answers are very interesting when working for optimal performance with respect to memory usage. Lazy loading might take longer to actually display the image, but it will save you working memory since you will not have all the images in memory.

Upvotes: 1

Tom Jonckheere
Tom Jonckheere

Reputation: 1648

I think it should be better if you would have an Article class with an image (or mayby better a reference to the image, so you only decode them when you need them), a title and a price variable. When you load the data you create an article... That way you are sure the article has the correct image, title and price...

Now you are depending on the order of 3 lists so mistakes are bound to happen!

Upvotes: 0

Ketan
Ketan

Reputation: 443

Hi You can use Lazy list for loading images properly. refer http://androidtutorialbd.blogspot.in/2013/03/lazy-list-view.html

Upvotes: 0

Related Questions