在onDraw方法中使用for循环在自定义视图上设置动画数字计数器

时间:2012-10-18 18:28:39

标签: android android-layout android-animation android-custom-view

如果这是正确的做法,我很困惑。请指正。所以基本上我在自定义视图中使用canvas.drawText方法绘制了一个文本。文本是数字(金额)。当事件发生时,我正试图使文本动画为另一个数字(例如:100 => 800)。

我知道这可以通过onDraw方法中的for循环计数器完成,并调用canvas.drawTextinvalidate()直到达到最终数字。但是我的应用程序被卡住了。

更新的代码:

我已经更新了代码。现在应用程序不会卡住(根据Simon的建议)。但现在它只是一次性绘制所有数字(1-99)。 我不知道如何放慢循环

public class CustomView extends View implements OnTouchListener{

   private Canvas main_canvas;

   //...Other codes like, initialization, paint etc!...//

   @Override
   protected void onDraw(Canvas canvas) {
      main_canvas = canvas;
   }

   public boolean onTouch(View v, MotionEvent event) {
      switch(event.getAction()){
      case MotionEvent.ACTION_DOWN:
      //...Some action...//
      case MotionEvent.ACTION_MOVE:
      //...Some action...//
      case MotionEvent.ACTION_UP:
      runTextAnimation();
      }
   }

   private void runTextAnimation() {

        for(int i=1; i < 100; i++){
            main_canvas.drawText(String.valueOf(i), getMeasuredWidth()/2, 100, amountPaint);
            invalidate();
        }
   }

}

2 个答案:

答案 0 :(得分:1)

我通过使用 Runnable 并使用postDelayed将消息排队几毫秒来解决这个问题。虽然我要感谢西蒙缩小我的搜索和想法。以下是片段。希望这可以帮助某人。欢呼声。

    private Handler mHandler;
    private int i;

    mHandler.post(mUpdate); //call this to run

    private Runnable mUpdate = new Runnable() {
               public void run() {

                main_canvas.drawText("Secret Text"+i, getMeasuredWidth()/2, 50, textPaint);

                i++; // incrementing the value

                mHandler.postDelayed(this, 60);
                invalidate();
                }
        };

顺便说一句,上面的片段是一个无限远的计数器,请注意在某个时候停止它。

答案 1 :(得分:0)

不要在onDraw()中使用invalidate()!

invalidate()导致onDraw()被调用,然后你使invalidate()导致onDraw()被调用,然后你使()无效 - 你明白了。循环应该在onDraw()之外,并使用invalidate来更新视图。但要小心,如果你的循环太快,你可能看不到所有更新,因为更新排队。

暂停线程一段时间:

Thread.sleep(50);

这睡眠时间为50毫秒。尝试一下,但我认为在UI线程上使用Runnable将是更好的解决方案。