5

目标 我想实现一个倒数计时器,它只是从左到右滚动数字(不是图形)。

效果 效果看起来像数字从左侧放大,向中间放慢,然后向右缩小。

备注 由于我已经使用 TimerTask 每秒执行代码,我可以使用它来触发下一个数字以在水平滚动的文本视图中滚动。

这可以实现为滚动视图中的文本视图吗?寻找一个代码示例开始......

4

2 回答 2

9

使用动画将是最简单的解决方案。您可以创建自己的或尝试组合多个TranslateAnimationsScaleAnimations

这意味着将每个数字放入其自己的 TextView 中,而不是使用滚动视图。

然后,您可以使用Interpolator控制到中间的加速度。插值器是 Android 处理缓动的方式。您可能需要AccelerateDecelerateInterpolator来实现加速/减速效果。

您可以使用AnimationSet将多个动画应用到同一个视图。弄清楚如何组合一个好的 AnimationSet 将是项目中最具挑战性的部分。请务必注意“填充”属性。事实上,在玩了一会儿之后,我认为自定义动画比使用现成的动画更简单。

你可以 fork我的 GitHub 项目,它实现了一个非常简单的版本。4 月 17 日及之前我使用了多个预制动画。如果您查看最新版本,您将看到自定义动画。

在您设置一个动画的持续时间后,每个动画的时间都会自行处理。处理程序在前一个号码完成后调用下一个号码。我认为这比每隔 X 秒调用一个函数来更新所有内容要简洁一些。

功能概述:

  • 一个 Activity ( CountDownActivity.java ) 可以看到一切。
    • Activitiy 的布局 XML 有一个用于开始倒计时的按钮。
    • 一旦倒计时开始,按钮就会消失。倒计时完成后它会重新出现。
  • Activity 包含一个处理程序( MotionHandler.java )。处理程序控制数字的移动和时间。
    • Handler 使用AnimationSet来移动数字
      • AnimationSet 是传入的依赖项
        • 这是为了灵活性。只需传入不同的 AnimationSet 即可更改数字的移动方式
        • AnimationSet 由四个动画组成,一个自定义动画(见下文)
    • AnimationSet 使用共享的AccelerateDecelerateInterpolator,这似乎工作得很好。还有其他选择,包括自己编写。
    • Handler 使用延迟消息开始下一个号码
    • 当倒计时完成时,处理程序会使用自定义侦听器(MotionHandler >> CountdownListener)通知 Activity
  • 旋转设备将重新开始倒计时。

注意 - 之前我在一个 AnimationSet 中使用了四个现成的动画,我已经编辑为只包含一个自定义动画......您可以根据自己的喜好调整其算法。

此自定义动画使用Cycloid使数字看起来越来越大。

/**
 * A custom animation to move and scale the numbers.
 * 
 */
public class NumberAnimation extends Animation
{
    final public static float MINIMUM = 3;
    private int mHorizontal;
    private int mScaling;

    public NumberAnimation(int horizontalMovement, int scaling)
    {
        mHorizontal = horizontalMovement;
        mScaling = scaling;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t)
    {
        // Cycloid repeats every 2pi - scale interpolatedTime to that
        double time = 2 * Math.PI * interpolatedTime;
        // Cycloid function
        float currentScale = (float) (mScaling * (1 - Math.cos(time))) + MINIMUM;
        Matrix matrix = t.getMatrix();
        matrix.preScale(currentScale, currentScale);
        matrix.postTranslate(mHorizontal * interpolatedTime, 0);
    }
}
于 2012-04-14T23:07:16.510 回答
0

动将帮助您控制速度。

于 2012-04-16T02:29:44.590 回答