Vaadin 21:将 Scroller 嵌套到 VerticalLayout 问题
Vaadin 21: Nesting Scroller into VerticalLayout problem
给定一个有 3 个嵌套 VerticalLayout
的 Composite
,每个都有全高
而一个Scroller
嵌套到最里面的VerticalLayout
,
Scroller
包含第四个 VerticalLayout
和 20 Button
s
Composite
渲染时
然后我希望最外面的 VerticalLayout
在屏幕上完全可见
VerticalLayout
s 和滚动条整齐地嵌套
Scroller
尽可能小,所以一切都适合屏幕
并且根本不可能滚动外部 VerticalLayout
s(只要屏幕足够大以容纳 4 VerticalLayout
s、一个 Scroller
和至少一个 Button
但是最外面的VerticalLayout
不适合屏幕
Scroller
允许滚动 Button
,但最后一个 Button
只能在滚动 3 个外部 VerticalLayout
时看到(这不应该发生)。
滚动 3 个外部 VerticalLayout
s 显示外部 VerticalLayout
s 的奇怪重叠。
初始状态
将Scroller
滚动到底部后
整个canvas滚动到底部后
如何实现所需的 nesting/scrolling 行为?
这是我的代码
@Route("3_scrollerx")
public class ScrollerxView extends Composite<Component> {
@Override
protected Component initContent() {
final VerticalLayout lvl1 = new VerticalLayout(new Label("lvl1"));
final VerticalLayout lvl2 = new VerticalLayout(new Label("lvl2"));
final VerticalLayout lvl3 = new VerticalLayout(new Label("lvl3"));
final Scroller scroller = new Scroller();
scroller.setContent(buildScrollerContent());
scroller.setHeightFull();
List.of(lvl1, lvl2, lvl3).forEach(layout -> {
layout.setHeightFull();
layout.getStyle().set("border", "1px solid");
});
scroller.getStyle().set("border", "1px solid");
lvl1.add(lvl2);
lvl2.add(lvl3);
lvl3.add(scroller); // always weird
return lvl1;
}
private VerticalLayout buildScrollerContent() {
final var scrollerContent = new VerticalLayout();
for (int i = 1; i <= 20; i++) {
scrollerContent.add(new Button("Button " + i));
}
scrollerContent.setHeightFull();
return scrollerContent;
}
}
我在第一次创建我的 Vaadin 应用程序的主要布局时处理了这个问题。它实际上是 flexbox 布局的样式问题,而不是 Vaadin 特有的。 VerticalLayout
对象的计算最小高度是其内容的高度。如果您在垂直布局上设置 css min-height: 0
,它将允许它们小于其内容。
您可以在此处了解更多信息:
由于开发人员忘记设置最小高度,这对我们来说一直是倒退。 VerticalLayout 很方便,但有很多主题和样式融入其中,可以很好地显示单独的控件。如果您正在寻找用于构建页面的可重用 flexbox 组件,请考虑创建一个新组件。
@Tag("column-layout")
@CssImport("layouts.css")
public class ColumnLayout extends Div {
public ColumnLayout(Component... components) {
super(components);
}
}
采用这种风格:
column-layout {
box-sizing: border-box;
display: flex;
flex-direction: column;
min-height: 0;
}
在您的示例中实现:
@Route("3_scrollerx")
public class ScrollerxView extends Composite<Component> {
@Override
protected Component initContent() {
final ColumnLayout lvl1 = new ColumnLayout(new Label("lvl1"));
final ColumnLayout lvl2 = new ColumnLayout(new Label("lvl2"));
final ColumnLayout lvl3 = new ColumnLayout(new Label("lvl3"));
VerticalLayout scrollerContent = buildScrollerContent();
List.of(lvl1, lvl2, lvl3, scrollerContent).forEach(layout -> {
layout.setHeightFull();
layout.getStyle().set("border", "1px solid");
});
lvl1.add(lvl2);
lvl2.add(lvl3);
lvl3.add(scrollerContent);
return lvl1;
}
private VerticalLayout buildScrollerContent() {
final var scrollerContent = new VerticalLayout();
for (int i = 1; i <= 20; i++) {
scrollerContent.add(new Button("Button " + i));
}
scrollerContent.getStyle().set("overflow", "auto");
return scrollerContent;
}
}
给定一个有 3 个嵌套 VerticalLayout
的 Composite
,每个都有全高
而一个Scroller
嵌套到最里面的VerticalLayout
,
Scroller
包含第四个 VerticalLayout
和 20 Button
s
Composite
渲染时
然后我希望最外面的 VerticalLayout
在屏幕上完全可见
VerticalLayout
s 和滚动条整齐地嵌套
Scroller
尽可能小,所以一切都适合屏幕
并且根本不可能滚动外部 VerticalLayout
s(只要屏幕足够大以容纳 4 VerticalLayout
s、一个 Scroller
和至少一个 Button
但是最外面的VerticalLayout
不适合屏幕
Scroller
允许滚动 Button
,但最后一个 Button
只能在滚动 3 个外部 VerticalLayout
时看到(这不应该发生)。
滚动 3 个外部 VerticalLayout
s 显示外部 VerticalLayout
s 的奇怪重叠。
初始状态
将Scroller
滚动到底部后
整个canvas滚动到底部后
如何实现所需的 nesting/scrolling 行为?
这是我的代码
@Route("3_scrollerx")
public class ScrollerxView extends Composite<Component> {
@Override
protected Component initContent() {
final VerticalLayout lvl1 = new VerticalLayout(new Label("lvl1"));
final VerticalLayout lvl2 = new VerticalLayout(new Label("lvl2"));
final VerticalLayout lvl3 = new VerticalLayout(new Label("lvl3"));
final Scroller scroller = new Scroller();
scroller.setContent(buildScrollerContent());
scroller.setHeightFull();
List.of(lvl1, lvl2, lvl3).forEach(layout -> {
layout.setHeightFull();
layout.getStyle().set("border", "1px solid");
});
scroller.getStyle().set("border", "1px solid");
lvl1.add(lvl2);
lvl2.add(lvl3);
lvl3.add(scroller); // always weird
return lvl1;
}
private VerticalLayout buildScrollerContent() {
final var scrollerContent = new VerticalLayout();
for (int i = 1; i <= 20; i++) {
scrollerContent.add(new Button("Button " + i));
}
scrollerContent.setHeightFull();
return scrollerContent;
}
}
我在第一次创建我的 Vaadin 应用程序的主要布局时处理了这个问题。它实际上是 flexbox 布局的样式问题,而不是 Vaadin 特有的。 VerticalLayout
对象的计算最小高度是其内容的高度。如果您在垂直布局上设置 css min-height: 0
,它将允许它们小于其内容。
您可以在此处了解更多信息:
由于开发人员忘记设置最小高度,这对我们来说一直是倒退。 VerticalLayout 很方便,但有很多主题和样式融入其中,可以很好地显示单独的控件。如果您正在寻找用于构建页面的可重用 flexbox 组件,请考虑创建一个新组件。
@Tag("column-layout")
@CssImport("layouts.css")
public class ColumnLayout extends Div {
public ColumnLayout(Component... components) {
super(components);
}
}
采用这种风格:
column-layout {
box-sizing: border-box;
display: flex;
flex-direction: column;
min-height: 0;
}
在您的示例中实现:
@Route("3_scrollerx")
public class ScrollerxView extends Composite<Component> {
@Override
protected Component initContent() {
final ColumnLayout lvl1 = new ColumnLayout(new Label("lvl1"));
final ColumnLayout lvl2 = new ColumnLayout(new Label("lvl2"));
final ColumnLayout lvl3 = new ColumnLayout(new Label("lvl3"));
VerticalLayout scrollerContent = buildScrollerContent();
List.of(lvl1, lvl2, lvl3, scrollerContent).forEach(layout -> {
layout.setHeightFull();
layout.getStyle().set("border", "1px solid");
});
lvl1.add(lvl2);
lvl2.add(lvl3);
lvl3.add(scrollerContent);
return lvl1;
}
private VerticalLayout buildScrollerContent() {
final var scrollerContent = new VerticalLayout();
for (int i = 1; i <= 20; i++) {
scrollerContent.add(new Button("Button " + i));
}
scrollerContent.getStyle().set("overflow", "auto");
return scrollerContent;
}
}