你好

所以我有以下问题.我有大约1500张Flutter 克牌的图片.我想在"图库"中显示它们,您可以在其中滚动浏览它们.我可以用ImageCell对象创建GridView,还可以向其中添加图像.现在我的问题是,如果我一次添加所有映像,逻辑上Java会因为堆错误而崩溃.我在列表中有图像url(本地文件).我如何实现它只加载15幅图像呢.如果我滚动,它将加载接下来的15个,并卸载旧的.因此,它将只加载实际可见图像的图像,而不是全部1500个.我该怎么做?我完全没有主意了.

这里是我的代码:

    public void initialize() {

    GridView<Image> gridView = new GridView<>();
    gridView.setCellFactory(gridView1 -> new ImageGridCell(true));
    Image image = new Image("C:\\Users\\nijog\\Downloads\\cardpictures\\01DE001.png");

    gridView.setCellWidth(340);
    gridView.setCellHeight(512);

    //Platform.runLater(()-> {
    //    for (int i = 0; i < 5000; i++){
    //        gridView.getItems().add(image);
    //    }
    //});

    Platform.runLater(() -> gridView.getItems().addAll(createImageListFromCardFiles()));

    borderPane.setCenter(gridView);

}

protected List<Image> createImageListFromCardFiles(){

    List<Image> imageViewList = new ArrayList<>();
    App.getCardService().getCardArray().stream()
            //.filter(Card::isCollectible)
            .sorted(Comparator.comparingInt(Card::getCost))
            .sorted(Comparator.comparing(Card::isChampion).reversed())
            .skip(0)
            //.limit(100)
            .forEach(card -> {
                try {
                    String url = String.format(App.pictureFolderPath +"%s.png", card.getCardCode());
                    imageViewList.add(new Image(url));
                } catch (Exception e) {
                    System.out.println("Picture file not found [CardCode = " + card.getCardCode() + "]");
                    App.logger.writeLog(Logger.Operation.EXCEPTION, "Picture file not found [CardCode = " + card.getCardCode() + "]");
                }
            });
    return imageViewList;
}

推荐答案

您可能不需要使用您描述的策略.您正在以340x512(174080像素)大小的单元格显示图像.图像存储是每像素4个字节,因此这是每幅图像696320个字节;其中1500个将消耗大约1GB.您只需确保以显示图像的大小加载图像(而不是其原始大小):

// imageViewList.add(new Image(url));
imageViewList.add(new Image(url, 340, 512, true, true, true));

如果以后需要全尺寸的图像(例如,如果希望用户从网格视图中 Select 图像并在更大的窗格中显示),只需从url重新加载即可.

如果您确实需要实施所描述的战略,GridView将提供现成的支持.只需保留URL列表,而不是Image,并根据需要使用自定义GridCell加载图像.这将大大减少内存消耗,同时需要更多的I/O(加载图像)和CPU(解析图像格式).

GridView个项目作为图像URL,存储为字符串.

然后您可以执行以下操作:

GridView<String> gridView = new GridView<>();
gridView.getItems().addAll(getAllImageURLs());

gridView.setCellFactory(gv -> new GridCell<>() {
    private final ImageView imageView = new ImageView();

    {
        imageView.fitWidthProperty().bind(widthProperty());
        imageView.fitHeightProperty().bind(heightProperty());
        imageView.setPreserveRatio(true);
    }

    @Override
    protected void updateItem(String url, boolean empty) {
        super.updateItem(url, empty);
        if (empty || url == null) {
            setGraphic(null);
        } else {
            double w = getGridView().getCellWidth();
            double h = getGridView().getCellHeight();
            imageView.setImage(new Image(url, w, h, true, true, true));
            setGraphic(imageView);
        }
    }
});


protected List<String> getAllImageURLs(){

    return App.getCardService().getCardArray().stream()
            // isn't the first sort redundant here?
            .sorted(Comparator.comparingInt(Card::getCost))
            .sorted(Comparator.comparing(Card::isChampion).reversed())
            .map(card -> String.format(App.pictureFolderPath +"%s.png", card.getCardCode()))
            .collect(Collectors.toList());
}

Java相关问答推荐

使用ExecutorService时在ThreadFactory中触发自定义newThread函数

如何粘合(合并)文件Lucene?

Android Studio—java—在onBindViewHolder中,将断点和空白添加到BackclerView中

Java .类参数不通过构造函数传递

当我已经安装了其他版本的Java时,如何在Mac OSX 14.3.1上安装Java 6?

多重延迟签名

如何让JavaFx应用程序识别依赖项?

用户填充的数组列表永不结束循环

Sack()步骤中的合并运算符未按预期工作

如何在我的世界中为互动增加冷却时间?

为什么Collectors.toList()不能保证易变性

如何在Spring Boot中创建可以将值传递给配置的&Enable&Quot;注释?

Android Java:已设置但未读取SharedPreferences

try 在两个不同数组的数字之间求平均值

Spring Framework6.1中引入的新RestClient是否有适合于测试的变体,就像RestTemplate和TestRestTemplate一样?

在整数列表中查找和可被第三个整数整除的对时出现无法解释的RunTimeError

在Java中将对象&转换为&q;HashMap(&Q)

如何对存储为字符串的大数字数组进行排序?

移动二维数组的行

元音变音字符:如何在 Java 中将Á<0x9c>转换为Ü?