0

Could someone please post a simple example of how to animate a TextView growing in height from 0dp to a dynamic value?

I would like to increase the height of a textview, but allow the user to SEE it like an animation. The only condition is I know my max height is variable and not known at run time. The maximum I want to allow is 100dp.

I've tried performing a simple for loop such as:

runOnUiThread(new Runnable() {
    public void run() {
        LayoutParams params = myTextView.getLayoutParams();
        int myMaxHeightValue = 100;
        for (int x=0; x<myMaxHeightValue; x++) {
            params.height = getDensityPixels(x);
            myTextView.setLayoutParams(params);
            Thread.Sleep(300);
        }
    }
});

public void getDensityPixels(int value) {
    float density = getResources().getDisplayMetrics.display;
    return (int) (value * density + 0.5f);
}

Can anyone provide just a simple example where I can provide the MAX height and watch the textview grow from 0dp height to the MAX dp height? When I use the code above, it does indeed increase to the max height of 100dp, but the screen locks while it is sizing rather than SHOWING me the increase as it occurs.

Any help is greatly appreciated!

Phil
  • 4,029
  • 9
  • 62
  • 107
  • Explain to me why the down vote? Asking a question is now frowned upon? – Phil Mar 12 '15 at 18:23
  • Try this: http://stackoverflow.com/a/6027569/4224337 , otherwise maybe you need to create a cutom TextView class and play with *onMeasure()* method – Rami Mar 12 '15 at 18:36
  • You are blocking the UI thread while you are doing your work, hence your screen freezes. Try doing your work in an `AsyncTask` and update the UI from the `onProgressUpdate` method. – Marcus Mar 12 '15 at 18:37

2 Answers2

2

Never use thread to perform UI/View animations. Android provide so many options for animation, like ObjectAnimator, ValueAnimator, View Animator

An example, as per your requirement.

    private void animateHeight() {
        TextView myTextView=null;
        int maxInDp = 100;
        int maxInPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                maxInDp, mLauncher.getResources().getDisplayMetrics());
        ObjectAnimator.ofInt(this, "btnHeight", maxInPx).setDuration(300).start(); // for better animation change duration , and set interpolator.
    }

    public int btnHeight = 0;

    public int getBtnHeight() {
        return btnHeight;
    }

    public void setBtnHeight(int height) {
        btnHeight = height;
        LayoutParams params = myTextView.getLayoutParams();
        params.height = btnHeight;
        myTextView.setLayoutParams(params);
    }
Sreejith B Naick
  • 1,203
  • 7
  • 13
  • Would you be able to give a bit more detail as to how I would call this? I've updated the code to use my TextView, and updated the setDuration to (1000) which allows for a slower animation. But what do you mean when you say for better animation change duration and set interpolator? – Phil Mar 12 '15 at 19:52
  • What i meant is, change duration and interpolation according to you requirements. To start the animation, call `animateHeight()` – Sreejith B Naick Mar 13 '15 at 06:47
  • So when do you call `setBtnHeight()`? – Ali Kazi Jan 09 '17 at 02:39
1

You are locking your Main thread by running your worker thread on it. To update your UI while doing work in the background, use an AsyncTask. This tutorial explains how to do it nicely.

Basically, your AsyncTask will look something like this (example from above tutorial)

public class DoSomethingTask extends AsyncTask<Void, String, Void> {

  private static final String TAG = "DoSomethingTask";
  private static final int DELAY = 5000; // 5 seconds
  private static final int RANDOM_MULTIPLIER = 10;

  @Override
  protected void onPreExecute() {
   Log.v(TAG, "starting the Random Number Task");
   super.onPreExecute();
  }

  @Override
  protected void onProgressUpdate(String... values) {

  //HERE is where you will be doing your UI updates

   Log.v(TAG, "reporting back from the Random Number Task");
   updateResults(values[0].toString());
   super.onProgressUpdate(values);
  }

  @Override
  protected Void doInBackground(Void... params) {

  //HERE is where you will be doing your work (your loop)

   Log.v(TAG, "doing work in Random Number Task");
   String text="";
   while (true) {
    if (isCancelled()) {
     break;
    }
    int randNum = (int) (Math.random() * RANDOM_MULTIPLIER);
    text = String.format(getString(R.string.service_msg), randNum);

    //This is how you tell your thread to update the UI
    publishProgress(text);

    try {
     Thread.sleep(DELAY);
    } catch (InterruptedException e) {
     Log.v(TAG, "Interrupting the Random Number Task");
    }
   }
   return null;
  }
}
Marcus
  • 6,697
  • 11
  • 46
  • 89
  • 1
    Just wanted to say thank you for your response too. You are absolutely correct, that's why the screen was locking until the loop completed. Thank you for your help as well!! – Phil Mar 15 '15 at 01:51