title: Simulate animation inside custom view on Android
body: <p>I have a custom view which looks like a spinning wheel with numbers from 0 to 9.
  Basically it scrolls down from 0 to 9 while I am downloading something from the server and when the value is returned, the animation stops on it. The animation is made by updating the Y value of the text I am drawing</p>
  
  <p>Some relevant code:</p>
  
  <pre><code>public class TimeSpinner extends View
  {
  
      .....
      private void initialize()
      {
      .....
  
          handler = new Handler();
          repetitiveRunnable = new Runnable() {
              @Override
              public void run() {
                  updateData();
              }
          };
  
      }
  
      public void updateData() {
  
          float delta = 3;
  
          mDigitY += delta;
          mDigitAboveY += delta;
          mDigitBelowY += delta;
  
          //Test if animation needs to stop
          if (mCurrentDigit == animateToDigit) {
              handler.removeCallbacks(repetitiveRunnable);
          } else {
              handler.postDelayed(repetitiveRunnable, 5);
          }
  
          invalidate();
      }
  
  
      public void startLoadingDigit() {
          handler.postDelayed(repetitiveRunnable, 5);
      }
  
      @Override
      protected void onDraw(Canvas canvas)
      {
          super.onDraw(canvas);
  
          canvas.drawText(mDigitString, mDigitX, mDigitY, mDigitPaint);
          canvas.drawText(mDigitAboveString, mDigitX, mDigitAboveY, mDigitPaint);
          canvas.drawText(mDigitBelowString, mDigitX, mDigitBelowY, mDigitPaint);
  
      }
  
  }
  </code></pre>
  
  <p>The problem is the UI thread has some drawing to do on the other views so depending on phone's speed the animation is not fluid. Is like having bad frame rate or sometimes it stops for half of second. On powerful devices is reasonable good.</p>
  
  <p>Now the question, what can I do make the animation smooth independent of what the app is doing ? The View is simple, not a SurfaceView. Should I use a thread somehow ? A code sample would be great.</p>
  
  <p>Later edit.</p>
  
  <p>I tried using an AsycTask for updating the Y coordinate</p>
  
  <pre><code>public class TimeSpinnerTask extends AsyncTask&lt;Void, Void, Void&gt; {
  
          @Override
          protected Void doInBackground(Void... arg0) {
              Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
  
              while (animationRunning) {
  
                  updateData();
                  publishProgress();
  
                  try {
                      Thread.sleep(35);
                  } catch (InterruptedException e) {
  
                  }
              }
              return null;
          }
  
  
          @Override
          protected void onProgressUpdate(Void... values) {
              invalidate();
              super.onProgressUpdate(values);
          }
  
          @Override
          protected void onPostExecute(Void result) {
              invalidate();
              super.onPostExecute(result);
          }
      }
  
  public void updateData() {
  
          mDigitY += delta;
          mDigitAboveY += delta;
          mDigitBelowY += delta;
  
          if (mDigitAboveY &gt; findCenterY(mCurrentDigit)) {
              setCurrentDigit(mDigitAbove);
          }
  
          if (mCurrentDigit == animateToDigit) {
  
              animationRunning = false;
  
              setCurrentDigit(animateToDigit);
          }
      }
  </code></pre>
  
  <p>While this does seem to be a bit smoother, on older devices I still get shutter, sometimes the animation even pauses for 1 seconds before continuing.</p>
  
  <p>The asynctask is started with <code>executeOnExecutor</code> and the view is shown over a Map control from Android Maps V2. The shuttering appears especially when the map is loading tiles.</p>
  
  <p>Maybe I didn't go with the best approach. Here is the final result I want to obtain:
  <img src="https://i.stack.imgur.com/caPEr.gif" alt="enter image description here">
  Any ideas ?</p>