本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
如何通过为位置添加动画来移动组件
目的。 为组件的像素位置添加动画(例如:将卡片从右侧滑动到中央)。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组合以实现不透明度效果。
深入了解
这个页面有帮助吗?感谢你的反馈!