virtualList如何横向浮动排列

virtualList默认是垂直布局,但我想把每一个实例做成图块,设置宽度,一行显示多个,可以实现吗

virtualList是不支持横向排列的。为什么不直接用 flexLayout 呢?

因为我的数据量很大,用flexlayout需要一次创建出所有的图块,导致界面打开速度变慢,所以想用virtualList,可以边滑动边加载

我实现了一个可以滚动加载数据的 Scroller,如下:

  1. 首先扩展 JmixScroller,实现下拉加载数据的逻辑:
public class MyScroller extends JmixScroller {
    @FunctionalInterface
    public interface ItemsProvider{
        Collection<Component> createItems();
    }

    public ItemsProvider itemsProvider;

    public void setItemsProvider(ItemsProvider itemsProvider) {
        this.itemsProvider = itemsProvider;
    }

    // 初始化组件,可以根据自己的需要修改
    public void initComponents(String width, String height) {
        setContent(new Div());
        setWidth(width);
        setHeight(height);

        // 这里的代码在浏览器中下拉时可以刷新数据
        getElement().executeJs("""
        var self = this;
        this.addEventListener("scroll", function(e) {
            if(self.scrollTop + self.clientHeight == self.scrollHeight) {
                self.$server.addItems();
            }
        });
        """);
    }

    // 这个注解表示可以在 JS 中调用该方法
    @ClientCallable
    public void addItems(){
        Collection<Component> items = itemsProvider.createItems();
        var content = getContent();

        if(content == null){
            System.out.println("please call initComponents() first");
        }

        if(content instanceof HasComponents hc){
            hc.add(items);
        }
    }
}
  1. 在视图中使用:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<view xmlns="http://jmix.io/schema/flowui/view"
      title="msg://blankView2.title">
    <layout>
        <div id="mainDiv" width="100%" height="100%">

        </div>
    </layout>
</view>
@Route(value = "blank-view2", layout = MainView.class)
@ViewController(id = "jmx2sp_BlankView2")
@ViewDescriptor(path = "blank-view2.xml")
public class BlankView2 extends StandardView {

    @ViewComponent
    private Div mainDiv;

    private int componentCount = 0;

    private MyScroller myScroller;

    @Subscribe
    public void onInit(final InitEvent event) {
        myScroller = new MyScroller();
        myScroller.initComponents("20em","100px");
        myScroller.setItemsProvider(this::addComponents);
        myScroller.addItems();
        mainDiv.add(myScroller);
    }

    public Collection<Component> addComponents() {
        return createSpans(componentCount);
    }


    private Collection<Component> createSpans(int start) {
        Collection<Component> spans = new ArrayList<>();
        for (int i = start; i < start + 100; i++) {
            spans.add(new Span("span " + i));
        }
        componentCount += 100;
        return spans;
    }
}

效果:
sc

这个 MyScroller, 还可以根据 手册中的指南 实现在 XML 和 Studio 中可用。