跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

如何使 Component 可滚动并调整 overscroll

目的。 任何 Component 都可以变成可滚动的容器:只需用 setScrollable(ScrollDirection) 声明方向。如果内容(子元素高度之和)超出了可见区域, ScrollEngine 会处理 pan、动量、fling 以及 overscroll(拉动超过限制时的弹性效果)。

使用的 API

  • Component.setScrollable(ScrollDirection dir, ScrollEngine... engine) — 启用滚动。engine 是可选的(默认:新建 ScrollEngine)。传入 null 作为 dir 以禁用。
  • UIConstants.ScrollDirection — 枚举,有三个值:HORIZONTAL、VERTICAL、BOTH。
  • Component.isScrollable() — 组件是否可滚动。
  • Component.scrollable() — 返回 Scrollable 对象(含 .engine),或 null。
  • Component.setShowScrollPosition(boolean) — 显示/隐藏滚动位置指示器。
  • ScrollEngine.setOverscroll(boolean x, boolean y) — 按轴开启/关闭弹性效果。默认:两者均为 true。
  • ScrollEngine.setupOverscroll(float distance, float speedMin, float speedMax) — 调整 overscroll 的回弹距离和速度。
  • ScrollEngine.setScrollListener(ScrollListener listener) — 每次偏移变化时的回调(接收 vx, vy)。
  • ScrollEngine.scrollTo(float x, float y) / scrollToStartSmooth() / scrollToEndSmooth() — 重新定位滚动位置。
  • ScrollEngine.setOverscrollEffect(OverscrollEffect effect) — 静态:定义/禁用(null)全局边缘灰色曲线;可通过 new OverscrollEffect().setColor(...).setMaxAlpha(...).setMaxArcHeight(...) 自定义。

完整示例(复制、粘贴并运行)

package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Component painel = new Component();
      painel.setLayout(new GridLayout(Position.CENTER, Position.START));
      for (int i = 0; i < 60; i++)
         painel.add(.95f, new Label("Linha " + i));

      painel.setScrollable(ScrollDirection.VERTICAL);   // 沿 Y 轴滚动

      // 滚动引擎的可选调整:
      painel.scrollable().engine.setOverscroll(true, false);   // 仅垂直方向弹性
      painel.setShowScrollPosition(true);                       // 位置指示器
      painel.scrollable().engine.setScrollListener((vx, vy) ->
         Debug.log("scrollY = " + vy));                         // 响应滚动

      add(LAY_FILL, painel);
   }
}

下面的片段只展示核心部分。要运行它,请将其放入上面的 MainWindow 骨架中。

最小片段

// 已在源码核实:Component.setScrollable(约 1027 行)+ ScrollEngine.java
Component painel = new Component();
painel.setLayout(new GridLayout(Position.CENTER, Position.START));
for (int i = 0; i < 60; i++)
   painel.add(.95f, new Label("Linha " + i));

painel.setScrollable(ScrollDirection.VERTICAL);   // 沿 Y 轴滚动

// 滚动引擎的可选调整:
painel.scrollable().engine.setOverscroll(true, false);   // 仅垂直方向弹性
painel.setShowScrollPosition(true);                       // 位置指示器
painel.scrollable().engine.setScrollListener((vx, vy) ->
   Debug.log("scrollY = " + vy));                         // 响应滚动

layout.add(1f, painel);

通过代码重新定位:

painel.scrollable().engine.scrollToStartSmooth();   // 带动画回到顶部
painel.scrollable().engine.scrollTo(0, 500);        // 跳转到偏移 y=500 px

诚实提示:没有现成的 pull-to-refresh

框架不提供现成的 “pull-to-refresh”(下拉刷新)小部件。现有的是 overscroll 效果(拉动超过限制时的弹性曲线),它纯粹是视觉/物理性的—— 它不会暴露一个“拉动 X 像素后松手”的回调供你触发刷新。如果需要该行为,你必须 通过 setScrollListener 监控偏移量并检测超过某个阈值的 overscroll 来手动构建它。 对于需要重新加载数据的大型列表,最好使用由按钮或自定义手势触发的 VirtualListView.reloadData()。

深入了解

  • 超大列表默认已可滚动(VirtualListView 内部会调用 setScrollable(VERTICAL)):参见 lista-virtual-grande.md。
这个页面有帮助吗?