我已经成功实现了这样的自定义列表中的延迟加载
我使用的代码在这里:Custom List With Images in Blackberry 在链接的问题中,我定位心脏图标的y坐标,我解决了链接问题的问题。
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.drawImage(300,
y+400,
heart.getWidth(), heart.getHeight(), heart,
0, 0, 0);
现在我想处理两者的点击事件;也就是说,对于列表行单击和单击心脏
为此,我看到了@Nate在Custom List Field click event写的帖子。但在该代码中,图像不是从服务器加载的,而是静态图像。我想用我的代码实现@Nate的代码(这是延迟加载)。
如果您有任何想法,请建议我该怎么做。在此先感谢
答案 0 :(得分:2)
假设您从我发布的in this answer代码开始,并使用您在this question to download images from a list of URLs中显示的代码,那么您应该能够通过以下更改实现延迟图像加载:
创建listener interface that gets notified when downloads complete:
public interface DownloadListener {
// invokes if download success
public void downloadSuccess(Bitmap bitmap);
// invokes if download failed
public void errorOccured();
}
然后,代表一个列表行CustomListRow
的Manager子类被修改为实现此接口,并在下载完成时更新_thumb
图像:
public class CustomListRow extends Manager implements DownloadListener, FieldChangeListener {
public void downloadSuccess(final Bitmap img) {
_data.setThumb(img);
// make sure bitmap is updated on the UI / main thread
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_thumb.setBitmap(img);
}
});
}
public void errorOccured() {
// TODO: handle error
}
然后,您需要添加一些代码来创建所有线程以在后台下载图像,并在图像下载完成时通知DownloadListeners
。您可以决定 where 来执行此操作。在我的示例中,我将在ListScreen
类中执行此操作,其中我实例化ListRander
数据对象和CustomListField
:
for (int i = 0; i < numberOfItem; i++) {
ListRander lr = new ListRander("Product Name " + i, icon); // icon is placeholder for thumbnail image
data.addElement(lr);
}
final CustomListField list = new CustomListField(data);
add(list);
list.setChangeListener(this);
pool = new ThreadPool(3); // 3 concurrent download threads
for (int i = 0; i < numberOfItem; i++) {
final int row = i;
// create a new runnable to download the next image, and resize it:
pool.assign(new Runnable() {
public void run() {
try {
String text=object[row].getJSONArray("UrlArray").getString(0).toString();
EncodedImage encodedImg = JPEGEncodedImage.encode(connectServerForImage(text), quality); //connectserverForImage load Images from server
EncodedImage logoThumbnail = sizeImage(encodedImg, Display.getWidth(), Display.getHeight()-100);
list.getRow(row).downloadSuccess(logoThumbnail.getBitmap());
} catch (Exception e) {
e.printStackTrace();
list.getRow(row).errorOccured();
}
}
}
});
}
您可以在ListScreen
构造函数中执行此操作,也可以在您拥有object[]
数组网址时执行此操作。
您需要向CustomListField
添加新方法:
public CustomListRow getRow(int row) {
return (CustomListRow)getField(row);
}
上面的代码还需要添加一个成员变量(在ListScreen
中)来创建一个线程池:
private ThreadPool pool;
此线程池实现基于this tutorial here,只需稍加修改,只需将ArrayList
(BlackBerry Java上不可用)更改为Vector
...并删除对{ Thread#destroy()
。您需要将该教程的ThreadPool
,WorkerThread
和Done
类复制到您的项目中。上面的示例我展示了一个3个线程的线程池。在单CPU智能手机上,2或3个线程可能适合您的需求。 Read more here如果您想获得应用程序的完美线程数。
注意:如果可能,您通常可以提高性能,如果您下载的应用程序大小恰好适合您的应用程序,而不是使用较大的图像加载网络,然后在应用程序内调整它们的大小。但是,我意识到这取决于对图像的Web服务器进行一些控制,而您可能没有。只是想以后的优化。
答案 1 :(得分:1)
我确信我在旅行中看到了这个问题的一个很好的答案,但现在找不到。我建议在这里查看BB论坛: http://supportforums.blackberry.com/t5/Java-Development/bd-p/java_dev 因为那里有类似的问题。
目前,只需要了解您需要做的事情:
将这些放在一起,你就有了解决方案。我知道并非无足轻重。祝好运。