How to auto size textview dynamically according to the length of the text in android?

There's now an official solution to this problem. Autosizing TextViews introduced with Android O are available in the Support Library 26 and is backwards compatible all the way down to Android 4.0.

https://developer.android.com/preview/features/autosizing-textview.html


Here's one way to do it, using the support library:

<androidx.appcompat.widget.AppCompatTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:breakStrategy="balanced" 
        android:gravity="center_horizontal"
        android:maxLines="1"
        android:text="Hello world" 
        android:textSize="300sp" 
        app:autoSizeTextType="uniform"
        tools:targetApi="o"/>

The android:breakStrategy allows making the text go to the next line nicely, instead of the default behavior which might break the words.

In gradle, use this:

implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
implementation 'com.google.android.material:material:1.0.0-beta01'

Or this:

implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'

Note that it's recommended to set layout restrictions on the TextView (width and/or height), to make sure you will get it right. All depends on your use case.


addTextChangedListener is a listener for Edit Tex. this listener watch the changes of editText and it has three different states.

EditText edt = someEditText;
edt.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        /*watch the editText on every input and changes, then mange the size by if statements and editText length*/
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (edt.getText().toString().length() > 10){
                edt.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSmall);
            }
            else if (edt.getText().toString().length() > 5){
                edt.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeMedium);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });

Updated: According to question you can create a component(custom view) and extend it from AppCompatTextView name as you want; in its initialization you can add below code:

public class CustomTextView extends AppCompatTextView {
Context ctx;

public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    ctx = context;
    init();
}

public CustomTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    ctx = context;
    init();
}

public CustomTextView(Context context) {
    super(context);
    ctx = context;
    init();
}

public void init() {
    setOnTouchListener(null);
    addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (getText().toString().length() > 10){
                setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeSmall);
            }
            else if (getText().toString().length() > 5){
                setTextSize(TypedValue.COMPLEX_UNIT_SP, textSizeMedium);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });
}

}

you must use it in xml instead of the usual textView