1

I want to implement something like this in my application: enter image description here That is, each image contains one heart icon. I want to handle the click event on heart click and for that I have the following code

list.setEmptyString("No Image Available", DrawStyle.HCENTER);
            list.setRowHeight(Display.getHeight() - 100);
            list.setSize(data.size());
            if (listVManager != null && listVManager.getFieldCount() > 0) {
                listVManager.deleteAll();
            }

            list.setCallback(new ListFieldCallback() {
                public void drawListRow(ListField list, Graphics graphics,
                        int index, int y, int w) {
                    int yPos = y + list.getRowHeight() - 1;
                    graphics.setColor(0x434343);
                    graphics.fillRect(0, y, w, list.getRowHeight());

                    if (logoThumbnailImage != null
                            && logoThumbnailImage.length > index
                            && logoThumbnailImage[index] != null) {
                        EncodedImage img = logoThumbnailImage[index];
                        graphics.drawImage(0, y + 10, Display.getWidth(),
                                Display.getHeight() - 100, img, 0, 0, 0);

                        graphics.drawText("Hello", 10,
                                Display.getHeight() - 150);
                        graphics.drawImage(Display.getWidth() - 70,
                                Display.getHeight() - 150 + 300,
                                heart.getWidth(), heart.getHeight(), heart,
                                0, 0, 0);
                    } else {
                        graphics.drawImage(
                                15,
                                y + 10,
                                Display.getWidth(),
                                Display.getHeight() - 100,
                                sizeImage(iconImage, Display.getWidth(),
                                        Display.getHeight() - 100), 0, 0, 0);

                    }

                    graphics.drawText("Hello", 10,
                            Display.getHeight() - 150);
                    graphics.drawLine(0, yPos, w, yPos);

                }

                public Object get(ListField listField, int index) {
                    return null;
                }

                public int getPreferredWidth(ListField listField) {
                    return Display.getWidth();
                }

                public int indexOfList(ListField listField, String prefix,
                        int start) {
                    return 0;
                }
            });
            listVManager.add(list);
            loadImages = new LoadImages(80, 80);
            loadImages.start();
        }
    });

here load image is thread that load images in background and store them in logoThumbnailImage array and invalidate list from there when the it loads the image.

The Load image thread class:

private class LoadImages extends Thread {

    int widthL;
    int heightL;
    LoadImages(int width, int height) {
        this.widthL = width;
        this.heightL = height;
    }

    public void run() {
        logoThumbnailImage=new EncodedImage[numberOfItem];
        if (object != null) {
            for (int i = 0; i < numberOfItem; i++) {                
                    try {
                        String text=object[i].getJSONArray("UrlArray").getString(0).toString();
                        EncodedImage encodedImg = JPEGEncodedImage.encode(connectServerForImage(text), quality);    //connectserverForImage load Images from server                     
                        logoThumbnailImage[i] = sizeImage(encodedImg, Display.getWidth(), Display.getHeight()-100);
                        list.invalidate();


                } catch (Exception e) 
                {
                        e.printStackTrace();
                    }

            }
        } else {
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    Dialog.alert("No Data Found");
                }
            });
        }
    }
}

The application runs smoothly but I got the following output: enter image description here

I have the following problem 1. The heart and description is displayed on only one list row. Can any one tell me what I am missing? 2. How to perform the click event on heart

Dinesh Chandra
  • 329
  • 1
  • 2
  • 27

1 Answers1

3

Having looked at this only briefly, the problem appears to be that you are, in places, ignoring the 'y' position that is passed in to your drawListRow() method:

        public void drawListRow(ListField list, Graphics graphics,
                int index, int y, int w) {

Effectively the 'canvas' that you should be using to paint the current row (the row identified using int index) is bounded by the rectangle (0, y, w, list.getRowHeight()).

In fact, you can actually paint anywhere in the extent that belongs to the ListField, i.e. the area you can paint onto is actually the rectangle (0, 0, list.getWidth(), list.getHeight()). You can do this, but you shouldn't. If you go outside your row's rectangle you will be painting over another row.

In your case, painting outside the selected row is exactly what your code does. You do this:

                graphics.drawText("Hello", 10,
                        Display.getHeight() - 150);

This will actually be positioned on the ListField, 10 pixels in from the left and Display.getHeight() - 150 down from the top. It will be positioned at this point in the ListField, regardless of which row you are painting. So every row will put the Hello text in the same place.

So when coding your drawListRow(), make sure you offset all the positions to stay within the bounds of the row you are supposed to be painting. The origin of the area you are painting is (0, y), so offset all vertical positions using y. Do not use Display.getHeight(), use list.getRowHeight() to get the height you can paint (starting at y), and do not use Display.getWidth(), use the w variable that is passed in to get the width that you can paint. All your graphics actions should occur within these bounds.

Peter Strange
  • 2,640
  • 11
  • 11
  • Can you tell me how to perform the click event on heart icon – Dinesh Chandra Oct 11 '13 at 11:45
  • If you can click anywhere in the row, this is simple, override navigationClick(). If a click on the heart is to be different to a click elsewhere in the row, this is not supported on a ListField. A ListField expects focus and clicks to be directed at the row, not a specific part of the row. There are coding ways around this, but they are not pretty. So if you have just a few rows (say less than 30), and this is essential, then use a different approach. Create a HorizontalFieldManager for each row, and add the rows to a VerticalFieldManager. Or use GridFieldManager or TableLayoutManager. – Peter Strange Oct 11 '13 at 13:39
  • I found the code written by @NATE to implement the same but in that case the images are static but in my case the images are downloading(and images may be in great number) form web services . Can I implement the same code ? here is the link for nate implementation for the same http://stackoverflow.com/questions/11483128/custom-list-field-click-event/11486480#11486480 – Dinesh Chandra Oct 11 '13 at 13:52
  • Only looked briefly at Nate's code. You will clearly have to change that code to allow you to put a place holder image in and the update once the actual images are available. But that aside, it seems his star is separately focusable and clickable, as is your 'heart', so that code should be perfect as a base for what you want. – Peter Strange Oct 11 '13 at 14:45
  • Can you suggest some logic , How to implement this in my code.As to in my case the list get invalidated every time as a new image enters in logoThumbnailImage array. But in Nate code there is no such logic. – Dinesh Chandra Oct 11 '13 at 18:25
  • @DineshChandra, Stack Overflow isn't really setup to have discussion "threads" like other sites. It's designed to have you ask one small question at a time. The answer I gave, that you link to, does allow your "list" to accept separate clicks on the **row**, and on the **image** (star icon in my example). The star click would be the heart click in your app, and my code handles that in `CustomListRow#onStarClicked()`. If you want to use that code, and also do lazy loading, I would ask a new question. Link to my answer and ask how you can extend that custom list to *lazy load* the images. – Nate Oct 11 '13 at 21:56
  • @Nate I have start a new thread regarding the same at http://stackoverflow.com/questions/19331454/custom-list-with-lazy-loading Please see the Question and suggest me how I can do That – Dinesh Chandra Oct 12 '13 at 07:17