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

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

如何通过为位置添加动画来移动组件

目的。 为组件的像素位置添加动画(例如:将卡片从右侧滑动到中央)。PositionAnimation 进行线性插值,且不会被夹紧到 [0,1] —— 非常适合坐标。

使用的 API

  • new PositionAnimation(float start, float end, float duration [, float fps]) —— 线性插值 start → end,不夹紧;duration 以秒计;fps 可选(默认 60)。
  • PositionAnimation.onUpdate(Runnable) / onComplete(Runnable) / getValue() / start() / stop() / cancel() —— 与 AlphaAnimation 属于同一族。
  • Component.setX(int) / Component.setY(int) —— 重新定位组件(返回 Component)。替代方案:当同时改变尺寸时使用 setBounds(int x, int y, int w, int h)。
  • Component.getY() / getWidth() / getHeight() —— 用于保留未被添加动画的轴。
  • Component.repaint() —— 静态方法;在 onUpdate 中必须调用(按需渲染)。

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

package com.exemplo;

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

/** 可执行的主界面:打开时将卡片从右侧滑向中央。 */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Card card = new Card();
      add(card);

      int fromX = Screen.width;          // 从屏幕外右侧开始
      int toX   = (Screen.width - card.width) / 2;   // 水平居中

      PositionAnimation slide = new PositionAnimation(fromX, toX, 0.4f);   // 400 ms
      slide.onUpdate(() ->
         {
            card.x = (int) slide.getValue();     // 只移动 X 轴;Y 保持不变(x 是公开字段)
            Component.repaint();                 // 没有它帧不会重绘
         })
         .onComplete(() -> Component.repaint())
         .start();
   }
}

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

最小片段

// 已在源码核实:PositionAnimation 线性无 clamp;Component.setX(int)/setY(int);repaint() 静态
Card card = new Card();
add(card);

int fromX = Screen.width;          // 从屏幕外右侧开始
int toX   = (Screen.width - card.getWidth()) / 2;   // 水平居中

PositionAnimation slide = new PositionAnimation(fromX, toX, 0.4f);   // 400 ms
slide.onUpdate(() ->
   {
      card.setX((int) slide.getValue());   // 只移动 X 轴;Y 保持不变
      Component.repaint();                 // 没有它帧不会重绘
   })
   .onComplete(() -> Component.repaint())
   .start();

细节:

  • 如果需要同时在 X 和 Y 上移动,请使用两个 PositionAnimation(每个轴一个),或在 onUpdate 中计算两者并应用 setBounds(x, y, w, h)。
  • setX/setY 会改变在父级中的绝对位置;在采用自动布局的屏幕上,优先为你直接控制其 bounds 的组件添加动画(避免与 Layout 冲突)。
  • 与 AlphaAnimation 不同,这里没有缓动:运动是匀速的。要实现平滑运动,请在你自己的函数中串接一个缓动,或与 AlphaAnimation 组合以实现不透明度效果。

深入了解

这个页面有帮助吗?