Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am taking data of variable sizes from the server and setting to a textView and i wanted the textview to resize according to the length of the text set.

It is given in the material design guidelines. How to go about coding it ?

Material Design Guidelines

link to the Guidelines - https://material.google.com/style/typography.html#typography-other-typographic-guidelines

like image 904
Jobin Lawrance Avatar asked Jun 13 '16 11:06

Jobin Lawrance


4 Answers

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

like image 189
Artem Russakovskii Avatar answered Nov 18 '22 01:11

Artem Russakovskii


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.

like image 38
android developer Avatar answered Nov 18 '22 02:11

android developer


Revision 26.0.1 of Support Library added support for autosizing in AppCompatTextView.

Developers can now let the size of their text expand or contract automatically based on the size and characteristics of the TextView, making it much easier to optimize the text size on different screens or with dynamic content.

Granularity

In Java:

Call the setAutoSizeTextTypeUniformWithConfiguration() method:

setAutoSizeTextTypeUniformWithConfiguration(int autoSizeMinTextSize, int autoSizeMaxTextSize, int autoSizeStepGranularity, int unit)

In XML:

Use the autoSizeMinTextSize, autoSizeMaxTextSize, and autoSizeStepGranularity attributes to set the auto-sizing dimensions in the layout XML file:

<android.support.v7.widget.AppCompatTextView
        android:id="@+id/autosizing_textview_presetsize" 
        android:layout_width="wrap_content" 
        android:layout_height="250dp" 
        android:layout_marginLeft="0dp" 
        android:layout_marginTop="0dp" 
        app:autoSizeMaxTextSize="100sp" 
        app:autoSizeMinTextSize="12sp" 
        app:autoSizeStepGranularity="2sp" 
        app:autoSizeText="uniform" 
        android:text="Hello World!" 
        android:textSize="100sp" 
        app:layout_constraintLeft_toLeftOf="parent" 
        app:layout_constraintTop_toTopOf="parent" />

Preset Sizes

In Java:

Call the setAutoSizeTextTypeUniformWithPresetSizes() method:

setAutoSizeTextTypeUniformWithPresetSizes(int[] presetSizes, int unit)

In XML:

Use the autoSizePresetSizes attribute in the layout XML file:

<android.support.v7.widget.AppCompatTextView 
        android:id="@+id/autosizing_textview_presetsize" 
        android:layout_width="wrap_content" 
        android:layout_height="250dp" 
        android:layout_marginLeft="0dp" 
        android:layout_marginTop="0dp" 
        app:autoSizeText="uniform" 
        app:autoSizePresetSizes="@array/autosize_text_sizes" 
        android:text="Hello World!" 
        android:textSize="100sp" 
        app:layout_constraintLeft_toLeftOf="parent" 
        app:layout_constraintTop_toTopOf="parent" />

To access the array as a resource, define the array in the res/values/arrays.xml file:

<array name="autosize_text_sizes">
    <item>10sp</item>
    <item>12sp</item>
    <item>20sp</item>
    <item>40sp</item>
    <item>100sp</item>
</array>
like image 10
Darish Avatar answered Nov 18 '22 00:11

Darish


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

like image 5
Payam Kokabi Avatar answered Nov 18 '22 00:11

Payam Kokabi