Пользовательский список с изображениями в Blackberry

Я хочу реализовать в своем приложении что-то вроде этого: введите сюда описание изображенияТо есть каждое изображение содержит один значок сердца . Я хочу обработать событие щелчка по щелчку сердца, и для этого у меня есть следующий код

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();
        }
    });

здесь загрузка изображения — это поток, который загружает изображения в фоновом режиме и сохраняет их в массиве logoThumbnailImage и аннулирует список оттуда, когда он загружает изображение.

Класс потока загрузки изображения:

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");
                }
            });
        }
    }
}

Приложение работает без сбоев, но я получил следующий вывод: введите здесь описание изображения

У меня следующая проблема 1. Сердце и описание отображаются только в одной строке списка. Может ли кто-нибудь сказать мне, что мне не хватает? 2. Как выполнить событие щелчка по сердцу


person Dinesh Chandra    schedule 09.10.2013    source источник


Ответы (1)


Взглянув на это только кратко, проблема, по-видимому, заключается в том, что вы местами игнорируете позицию «y», которая передается вашему методу drawListRow():

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

Фактически «холст», который вы должны использовать для рисования текущей строки (строка, идентифицированная с помощью индекса int), ограничен прямоугольником (0, y, w, list.getRowHeight()).

На самом деле вы можете рисовать в любом месте экстента, принадлежащего ListField, то есть область, которую вы можете рисовать, на самом деле является прямоугольником (0, 0, list.getWidth(), list.getHeight()). Вы можете это сделать, но не должны. Если вы выйдете за пределы прямоугольника вашей строки, вы будете рисовать поверх другой строки.

В вашем случае рисование за пределами выбранной строки - это именно то, что делает ваш код. Ты делаешь это:

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

На самом деле это будет расположено в ListField, на 10 пикселей слева и Display.getHeight() - на 150 вниз сверху. Он будет расположен в этой точке ListField, независимо от того, какую строку вы рисуете. Таким образом, каждая строка будет помещать текст Hello в одно и то же место.

Поэтому при написании кода drawListRow() убедитесь, что вы смещаете все позиции, чтобы оставаться в пределах строки, которую вы должны рисовать. Исходная точка области, которую вы рисуете, равна (0, y), поэтому сместите все позиции по вертикали, используя y. Не используйте Display.getHeight(), используйте list.getRowHeight(), чтобы получить высоту, которую вы можете нарисовать (начиная с y), и не используйте Display.getWidth(), используйте переменную w, которая передается, чтобы получить ширину что ты умеешь рисовать. Все ваши графические действия должны происходить в этих пределах.

person Peter Strange    schedule 09.10.2013
comment
Можете ли вы сказать мне, как выполнить событие щелчка на значке сердца? - person Dinesh Chandra; 11.10.2013
comment
Если вы можете щелкнуть в любом месте строки, это просто, переопределите navigationClick(). Если щелчок на сердце должен отличаться от щелчка в другом месте строки, это не поддерживается в ListField. ListField ожидает, что фокус и щелчки будут направлены на строку, а не на конкретную часть строки. Есть способы обойти это, но они некрасивы. Поэтому, если у вас всего несколько строк (скажем, меньше 30), а это важно, используйте другой подход. Создайте HorizontalFieldManager для каждой строки и добавьте строки в VerticalFieldManager. Или используйте GridFieldManager или TableLayoutManager. - person Peter Strange; 11.10.2013
comment
Я нашел код, написанный @NATE для реализации того же самого, но в этом случае изображения статичны, но в моем случае изображения загружаются (и изображений может быть в большом количестве) из веб-сервисов. Могу ли я реализовать тот же код? вот ссылка на реализацию nate для того же stackoverflow.com/questions/11483128/ - person Dinesh Chandra; 11.10.2013
comment
Только мельком взглянул на код Нейта. Вам явно придется изменить этот код, чтобы вы могли поместить замещающее изображение и обновить его, как только фактические изображения будут доступны. Но помимо этого кажется, что его звезда отдельно фокусируется и кликабельна, как и ваше «сердце», так что этот код должен быть идеальным в качестве основы для того, что вы хотите. - person Peter Strange; 11.10.2013
comment
Можете ли вы предложить некоторую логику, как реализовать это в моем коде. Что касается моего случая, то список становится недействительным каждый раз, когда новое изображение входит в массив logoThumbnailImage. Но в коде Nate такой логики нет. - person Dinesh Chandra; 11.10.2013
comment
@DineshChandra, Stack Overflow на самом деле не настроен для обсуждения тем, как на других сайтах. Он предназначен для того, чтобы вы задавали один небольшой вопрос за раз. Ответ, который я дал, на который вы ссылаетесь, позволяет вашему списку принимать отдельные клики по строке и по изображению (значок звездочки в моем примере). Щелчок по звездочке будет щелчком сердца в вашем приложении, и мой код обрабатывает это в CustomListRow#onStarClicked(). Если вы хотите использовать этот код, а также выполнить отложенную загрузку, я бы задал новый вопрос. Ссылка на мой ответ и спросите, как вы можете расширить этот пользовательский список для ленивой загрузки изображений. - person Nate; 12.10.2013
comment
@Nate Я начал новую тему по этому поводу в stackoverflow .com/questions/19331454/ Пожалуйста, посмотрите вопрос и предложите мне, как я могу это сделать - person Dinesh Chandra; 12.10.2013