title: Text scale up to fit a TextView and an EditText
body: <p>I want to fit the <code>text size</code> of a <code>TextView</code> and an <code>EditText</code> to to match their bounds.
  I searched a bit and found the code below. So I created a new class with the code below:</p>
  
  <pre><code>package com.example.test;
  
  
  import android.content.Context;
  import android.text.Layout.Alignment;
  import android.text.StaticLayout;
  import android.text.TextPaint;
  import android.util.AttributeSet;
  import android.util.TypedValue;
  import android.widget.TextView;
  
  
  public class AutoResizeTextView extends TextView {
  
  
          // Minimum text size for this text view
          public static final float MIN_TEXT_SIZE = 20;
  
          // Interface for resize notifications
          public interface OnTextResizeListener {
              public void onTextResize(TextView textView, float oldSize, float newSize);
          }
  
          // Our ellipse string
          private static final String mEllipsis = "...";
  
          // Registered resize listener
          private OnTextResizeListener mTextResizeListener;
  
          // Flag for text and/or size changes to force a resize
          private boolean mNeedsResize = false;
  
          // Text size that is set from code. This acts as a starting point for resizing
          private float mTextSize;
  
          // Temporary upper bounds on the starting text size
          private float mMaxTextSize = 0;
  
          // Lower bounds for text size
          private float mMinTextSize = MIN_TEXT_SIZE;
  
          // Text view line spacing multiplier
          private float mSpacingMult = 1.0f;
  
          // Text view additional line spacing
          private float mSpacingAdd = 0.0f;
  
          // Add ellipsis to text that overflows at the smallest text size
          private boolean mAddEllipsis = true;
  
          // Default constructor override
          public AutoResizeTextView(Context context) {
              this(context, null);
          }
  
          // Default constructor when inflating from XML file
          public AutoResizeTextView(Context context, AttributeSet attrs) {
              this(context, attrs, 0);
          }
  
          // Default constructor override
          public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) {
              super(context, attrs, defStyle);
              mTextSize = getTextSize();
          }
  
          /**
           * When text changes, set the force resize flag to true and reset the text size.
           */
          @Override
          protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
              mNeedsResize = true;
              // Since this view may be reused, it is good to reset the text size
              resetTextSize();
          }
  
          /**
           * If the text view size changed, set the force resize flag to true
           */
          @Override
          protected void onSizeChanged(int w, int h, int oldw, int oldh) {
              if (w != oldw || h != oldh) {
                  mNeedsResize = true;
              }
          }
  
          /**
           * Register listener to receive resize notifications
           * @param listener
           */
          public void setOnResizeListener(OnTextResizeListener listener) {
              mTextResizeListener = listener;
          }
  
          /**
           * Override the set text size to update our internal reference values
           */
          @Override
          public void setTextSize(float size) {
              super.setTextSize(size);
              mTextSize = getTextSize();
          }
  
          /**
           * Override the set text size to update our internal reference values
           */
          @Override
          public void setTextSize(int unit, float size) {
              super.setTextSize(unit, size);
              mTextSize = getTextSize();
          }
  
          /**
           * Override the set line spacing to update our internal reference values
           */
          @Override
          public void setLineSpacing(float add, float mult) {
              super.setLineSpacing(add, mult);
              mSpacingMult = mult;
              mSpacingAdd = add;
          }
  
          /**
           * Set the upper text size limit and invalidate the view
           * @param maxTextSize
           */
          public void setMaxTextSize(float maxTextSize) {
              mMaxTextSize = maxTextSize;
              requestLayout();
              invalidate();
          }
  
          /**
           * Return upper text size limit
           * @return
           */
          public float getMaxTextSize() {
              return mMaxTextSize;
          }
  
          /**
           * Set the lower text size limit and invalidate the view
           * @param minTextSize
           */
          public void setMinTextSize(float minTextSize) {
              mMinTextSize = minTextSize;
              requestLayout();
              invalidate();
          }
  
          /**
           * Return lower text size limit
           * @return
           */
          public float getMinTextSize() {
              return mMinTextSize;
          }
  
          /**
           * Set flag to add ellipsis to text that overflows at the smallest text size
           * @param addEllipsis
           */
          public void setAddEllipsis(boolean addEllipsis) {
              mAddEllipsis = addEllipsis;
          }
  
          /**
           * Return flag to add ellipsis to text that overflows at the smallest text size
           * @return
           */
          public boolean getAddEllipsis() {
              return mAddEllipsis;
          }
  
          /**
           * Reset the text to the original size
           */
          public void resetTextSize() {
              if(mTextSize &gt; 0) {
                  super.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
                  mMaxTextSize = mTextSize;
              }
          }
  
          /**
           * Resize text after measuring
           */
          @Override
          protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
              if(changed || mNeedsResize) {
                  int widthLimit = (right - left) - getCompoundPaddingLeft() - getCompoundPaddingRight();
                  int heightLimit = (bottom - top) - getCompoundPaddingBottom() - getCompoundPaddingTop();
                  resizeText(widthLimit, heightLimit);
              }
              super.onLayout(changed, left, top, right, bottom);
          }
  
  
          /**
           * Resize the text size with default width and height
           */
          public void resizeText() {
              int heightLimit = getHeight() - getPaddingBottom() - getPaddingTop();
              int widthLimit = getWidth() - getPaddingLeft() - getPaddingRight();
              resizeText(widthLimit, heightLimit);
          }
  
          /**
           * Resize the text size with specified width and height
           * @param width
           * @param height
           */
          public void resizeText(int width, int height) {
              CharSequence text = getText();
              // Do not resize if the view does not have dimensions or there is no text
              if(text == null || text.length() == 0 || height &lt;= 0 || width &lt;= 0 || mTextSize == 0) {
                  return;
              }
  
              // Get the text view's paint object
              TextPaint textPaint = getPaint();
  
              // Store the current text size
              float oldTextSize = textPaint.getTextSize();
              // If there is a max text size set, use the lesser of that and the default text size
              float targetTextSize = mMaxTextSize &gt; 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;
  
              // Get the required text height
              int textHeight = getTextHeight(text, textPaint, width, targetTextSize);
  
              // Until we either fit within our text view or we had reached our min text size, incrementally try smaller sizes
              while(textHeight &gt; height &amp;&amp; targetTextSize &gt; mMinTextSize) {
                  targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
                  textHeight = getTextHeight(text, textPaint, width, targetTextSize);
              }
  
              // If we had reached our minimum text size and still don't fit, append an ellipsis
              if(mAddEllipsis &amp;&amp; targetTextSize == mMinTextSize &amp;&amp; textHeight &gt; height) {
                  // Draw using a static layout
                  StaticLayout layout = new StaticLayout(text, textPaint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
                  // Check that we have a least one line of rendered text
                  if(layout.getLineCount() &gt; 0) {
                      // Since the line at the specific vertical position would be cut off,
                      // we must trim up to the previous line
                      int lastLine = layout.getLineForVertical(height) - 1;
                      // If the text would not even fit on a single line, clear it
                      if(lastLine &lt; 0) {
                          setText("");
                      }
                      // Otherwise, trim to the previous line and add an ellipsis
                      else {
                          int start = layout.getLineStart(lastLine);
                          int end = layout.getLineEnd(lastLine);
                          float lineWidth = layout.getLineWidth(lastLine);
                          float ellipseWidth = textPaint.measureText(mEllipsis);
  
                          // Trim characters off until we have enough room to draw the ellipsis
                          while(width &lt; lineWidth + ellipseWidth) {
                              lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
                          }
                          setText(text.subSequence(0, end) + mEllipsis);
                      }
                  }
              }
  
              // Some devices try to auto adjust line spacing, so force default line spacing
              // and invalidate the layout as a side effect
              textPaint.setTextSize(targetTextSize);
              setLineSpacing(mSpacingAdd, mSpacingMult);
  
              // Notify the listener if registered
              if(mTextResizeListener != null) {
                  mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
              }
  
              // Reset force resize flag
              mNeedsResize = false;
          }
  
          // Set the text size of the text paint object and use a static layout to render text off screen before measuring
          private int getTextHeight(CharSequence source, TextPaint paint, int width, float textSize) {
              // Update the text paint object
              paint.setTextSize(textSize);
              // Measure using a static layout
              StaticLayout layout = new StaticLayout(source, paint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true);
              return layout.getHeight();
          }
  
      }
  </code></pre>
  
  <p>But what do I have to do from there in order for the code to work? This is my code and my XML file. What do I do wrong and what should I do?</p>
  
  <p>Java:</p>
  
  <pre><code>package com.example.test;
  
  import android.app.Activity;
  import android.media.MediaPlayer;
  import android.media.MediaPlayer.OnPreparedListener;
  import android.net.Uri;
  import android.os.Bundle;
  import android.view.WindowManager;
  import android.widget.EditText;
  import android.widget.VideoView;
  import com.example.test.AutoResizeTextView;
  
  public class MainActivity extends Activity {
  
  
      public VideoView vv;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
  
          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  // Set Fullscreen mode, overiding title and BATTERY
                  WindowManager.LayoutParams.FLAG_FULLSCREEN);
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // SCREEN NEVER GOES TO SLEEP MODE
  
       //*** BACKGROUND MOVIE, LOOPING AND SETTING LOCAL PATH ***
         vv = (VideoView) findViewById(R.id.videoView);
          vv.setOnPreparedListener(new OnPreparedListener() {
              @Override
              public void onPrepared(MediaPlayer mp) {
                  mp.setLooping(true);
              }
          });
  
         Uri url=Uri.parse("android.resource://" + getPackageName() +"/"+ R.raw.bubblessd );
         vv.setVideoURI(url);
         vv.start();
         vv.requestFocus();
         //*** BACKGROUND MOVIE, LOOPING AND SETTING LOCAL PATH ***
      }
  
  
  final EditText myet = (EditText) findViewById(R.id.editText1);
  myet.resizeText();
  
  
  
  }
  </code></pre>
  
  <p>and XML:</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      style="@style/AppTheme"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:fitsSystemWindows="true"
      android:gravity="center"
      android:soundEffectsEnabled="false"
      tools:context=".MainActivity" &gt;
  
  
      &lt;VideoView
          android:id="@+id/videoView"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:layout_alignParentTop="true"
                           android:layout_alignParentBottom="true"
                           android:layout_alignParentLeft="true"
                           android:layout_alignParentRight="true" /&gt;
  
      &lt;LinearLayout 
          android:id = "@+id/main_menu_wrapper"
                      android:layout_width="fill_parent"
                      android:layout_height="fill_parent"
                      android:gravity="center"
                      android:orientation="vertical"
                      android:weightSum="100"&gt;
  
  
          &lt;LinearLayout
              android:layout_width="fill_parent"
              android:layout_height="0dip"
              android:layout_weight="20"
              android:fitsSystemWindows="true"
              android:gravity="center"
              android:orientation="horizontal"
              android:weightSum="100" &gt;
  
  
          &lt;com.example.test.AutoResizeTextView
              android:id="@+id/textView1"
              android:layout_width="0dp"
              android:layout_height="fill_parent"
              android:layout_weight="20"
              android:background="#55000000"
              android:text="TextView" 
              /&gt;
  
                      &lt;EditText
                          android:id="@+id/editText1"
                          android:layout_width="0dp"
                          android:layout_height="fill_parent"
                          android:layout_weight="20"
                          android:background="#55000000"
                          android:inputType="text"
                          android:maxLength="10"
                          android:shadowColor="#000"
                          android:textColor="#FFFFFF"
                          android:textStyle="bold" &gt;
  
         &lt;/EditText&gt;  
             &lt;/LinearLayout&gt; 
  
          &lt;/LinearLayout&gt;
  
  
  
  &lt;/RelativeLayout&gt;
  </code></pre>