【问题标题】:How to create a count-up effect for a textView in Android如何在 Android 中为 textView 创建计数效果
【发布时间】:2012-04-01 23:26:42
【问题描述】:

我正在开发一个应用程序来计算几段文本中问号的数量。

扫描完成后(完全不需要时间),我希望在数字从 0 变为 TOTAL 后显示总数。所以,对于 10:0,1,2,3,4,5,6,7,8,9 10 然后停止。

我尝试了几种不同的技术:

                TextView sentScore = (TextView) findViewById(R.id.sentScore);

                long freezeTime = SystemClock.uptimeMillis();

                for (int i = 0; i < sent; i++) {
                    if ((SystemClock.uptimeMillis() - freezeTime) > 500) {
                        sentScore.setText(sent.toString());
                    }
                }

我也试过这个:

    for (int i = 0; i < sent; i++) { 
        // try {
            Thread.sleep(500);

        } catch (InterruptedException ie) {
            sentScore.setText(i.toString()); 
        } 
    }

我确信这些都是完全业余的尝试。任何帮助将不胜感激。

谢谢,

理查德

【问题讨论】:

  • 如果你在 UI 线程上使用 sleep 方法,那么你的应用程序的主线程,那么不要。它将阻塞界面,用户在那段时间将无法做任何事情。
  • 这正是发生的事情。关于如何实现我想要的效果的任何想法?
  • 这里已经很晚了,我很累,所以我不能完全按照你想做的事情,但为了避免界面冻结,你必须在单独的线程中设置 sleep 方法。要么创建一个并将你的 sleep 方法放在那里,或者我不确定我很久以前使用它,有某种类型的计时器来自 Java 或 Android 平台,它会自动创建一个单独的线程,你可以附加一个回调函数,因此它每 500 毫秒执行一次。只需谷歌 java timers 或 android timers 或只是等待这里的人告诉你:P 哈哈。我现在累了 2 :)

标签: java android android-layout


【解决方案1】:

也许尝试将 for 循环更改为:

int count = 0;
while (count != sent) {
    if ((SystemClock.uptimeMillis() - freezeTime) > 500) {
        count++;
        sentScore.setText("" + count);
        freezeTime = SystemClock.uptimeMillis();
    }
}

【讨论】:

  • 不幸的是,这只会立即将正确的总数推送到视图中。我不得不将 sentScore 更改为已发送。那是保存总数的变量的名称。
  • 使用单独的线程和睡眠更好,正如 slukian 刚刚发布的那样。
【解决方案2】:

试试这个:

private int counter = 0;
private int total = 30; // the total number
//...
//when you want to start the counting start the thread bellow.
    new Thread(new Runnable() {

                public void run() {
                    while (counter < total) {
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        t.post(new Runnable() {

                            public void run() {
                                t.setText("" + counter);

                            }

                        });
                        counter++;
                    }

                }

            }).start();

【讨论】:

  • 非常感谢您抽出宝贵的时间来写这篇文章。现在我有一个方法可以获取文本消息并计算调用的消息:protected void onActivityResult(int requestCode, int resultCode, Intent data) { 在那之后我要启动线程吗?还是在其中?如果我从该方法中启动可运行线程,我似乎无法让它工作。
  • @burtonic 从那个回调方法启动线程应该没有问题,当你得到总数然后启动线程。(onActivityResult是一个回调方法,当你期望什么时调用从您以 startActivityForResult()) 开始的子活动。请注意,TextView 应该是 final,以便您可以从该匿名类访问它。
  • 稍微重新调整一下,它完全按我想要的方式工作。谢谢! cl.ly/0X0H0M1Y3Y3L1j3g1C2d
  • 直接使用Animator不是更好吗?我也读过 Thread 不好,使用 Handler 代替 Android。
  • @HendraWD 我的答案是在 2012 年发布的,显然当前的 Animator 课程是一个更好的选择(看看 marmor 的答案)。线程和处理程序不是一回事,所以我不明白你的意思。
【解决方案3】:

使用工作线程进行等待并更新您的 UI 线程。

您可以使用 AsyncTask,尽管这对于这项工作来说可能有点过头了。如果你使用它,在 doInBackground() 循环中遍历睡眠周期的数量并在每个睡眠周期之后,更新 UIthread 中的计数。

给你! Slukain 刚刚给了你工作代码:P

【讨论】:

    【解决方案4】:

    使用TextSitcher

    以获得最佳效果。它会柔和地变换文本。

    当要更改文本时,请使用以下代码。

    > int number = 0;
    >         Timer obj = new Timer();
    >         TimerTask tt = new TimerTask() {
    >                       @Override           public void run() {
    >               // TODO Auto-generated method stub
    >               textView.setText(number++);
    >               if(number < score)
    >               obj.schedule(tt, 200);          }       };
    >         obj.schedule(tt, 200);
    

    【讨论】:

    • 我相信你的意思是TextSwitcher 对吧?您应该已经发布了一个更完整的代码片段来展示它的使用。但是,还是要提一下那个甜甜的课:)
    【解决方案5】:

    我为此使用了更传统的 Android 风格动画:

            ValueAnimator animator = new ValueAnimator();
            animator.setObjectValues(0, count);
            animator.addUpdateListener(new AnimatorUpdateListener() {
                public void onAnimationUpdate(ValueAnimator animation) {
                    view.setText(String.valueOf(animation.getAnimatedValue()));
                }
            });
            animator.setEvaluator(new TypeEvaluator<Integer>() {
                public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
                    return Math.round(startValue + (endValue - startValue) * fraction);
                }
            });
            animator.setDuration(1000);
            animator.start();
    

    您可以使用0count 值使计数器从任意数字变为任意数字,并使用1000 设置整个动画的持续时间。

    请注意,这支持 Android API 级别 11 及更高版本,但您可以使用很棒的 nineoldandroids 项目使其轻松向后兼容。

    【讨论】:

    • 如果 startValue 不是 0,则无法正常工作。您必须更新评估函数以返回 startValue + (endValue - startValue) * 分数。除了出色的工作!
    • 双倍的工作原理是什么?我收到错误 java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
    • 您需要将 TypeEvaluator 更改为 TypeEvaluator 并从评估方法返回一个浮点数
    【解决方案6】:

    这个问题很老了,但我发布这个问题是为了帮助其他人。 我用过这两个很棒的库。

    试试看

    1. https://github.com/MasayukiSuda/CountAnimationTextView

    或者 2.https://github.com/robinhood/ticker

    希望这会有所帮助 :) 编码快乐!!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-02
      • 2017-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 1970-01-01
      • 2017-04-27
      相关资源
      最近更新 更多