[android] Text size and different android screen sizes

I know, it was discussed already 1000 times, but I can't adjust the text size for different screen sizes. I try to use 'sp' as size units in my custom style:

<style name="CustumButtonStyle" parent="@android:style/Widget.Button">
    ...
    <item name="android:textSize">30sp</item>
    ...
</style>

In 2.7 QVGA it looks OK:

2.7QVGA 30sp

But in 7in WSVGA it looks like this:

7in WSVGA 30sp

I've tried to use both 'sp' and 'dp' with the same result.

Could you please explain how to make these buttons look the same on any screen?

The full custom button style

<style name="CustumButtonStyle" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/custom_button</item>
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_margin">3dp</item>
    <item name="android:textColor">#ffffff</item>
    <item name="android:gravity">center</item>
    <item name="android:textSize">30sp</item>
    <item name="android:textStyle">bold</item>
    <item name="android:shadowColor">#000000</item>
    <item name="android:shadowDx">1</item>
    <item name="android:shadowDy">1</item>
    <item name="android:shadowRadius">2</item>
</style>

And in my application theme I have

<item name="android:buttonStyle">@style/CustumButtonStyle</item>

And there is my layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="fill_parent"
android:background="@drawable/grid"
android:gravity="center"
android:orientation="vertical" android:layout_height="fill_parent">

<Button
    android:id="@+id/buttonContinue"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="@string/continue_game" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"/>



<Button
    android:id="@+id/buttonNewGame"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/buttonContinue"
    android:layout_alignRight="@+id/buttonContinue"
    android:layout_below="@+id/buttonContinue"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="@string/new_game" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"/>



<Button
    android:id="@+id/ButtonAbout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/buttonNewGame"
    android:layout_alignRight="@+id/buttonNewGame"
    android:layout_below="@+id/buttonNewGame"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="@string/about" android:layout_marginTop="3dp" android:layout_marginBottom="3dp"/>

This question is related to android screen-size text-size

The answer is


I know it's late but this might help someone...

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:autoSizeTextType="uniform"
        android:gravity="center_horizontal|bottom"
        android:text="Your text goes here!"
        android:layout_centerInParent="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.05"
        app:layout_constraintHorizontal_bias="0.50"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.50"
        app:layout_constraintWidth_percent="0.50" />
</androidx.constraintlayout.widget.ConstraintLayout>

Also, if you want to adjust the text size then try changing

app:layout_constraintWidth_percent="0.50" 
app:layout_constraintHeight_percent="0.05"

That's all.


As @espinchi mentioned from 3.2 (API level 13) size groups are deprecated. Screen size ranges are the favored approach going forward.


I think you can archive that by add multiple layout resource for each screen size, example:

res/layout/my_layout.xml             // layout for normal screen size ("default")
res/layout-small/my_layout.xml       // layout for small screen size with small text
res/layout-large/my_layout.xml       // layout for large screen size with larger text
res/layout-xlarge/my_layout.xml      // layout for extra large screen size with even larger text
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation

Reference: 1.http://developer.android.com/guide/practices/screens_support.html


If you have API 26 then you might consider using autoSizeTextType:

<Button
  app:autoSizeTextType="uniform" />

Default setting lets the auto-sizing of TextView scale uniformly on horizontal and vertical axes.

https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview


I think its too late to reply on this thread. But I would like to share my idea or way to resolve text size problem over difference resolution devices. Many android developer sites suggest that we have to use sp unit for text size which will handle text size for difference resolution devices. But I am always unable to get the desired result. So I have found one solution which I am using from my last 4-5 projects and its working fine. As per my suggestion, you have to place the text size for each resolution devices, which is bit tedious work, but it will fulfill your requirement. Each developer has must listen about the ratio like 4:6:8:12 (h:xh:xxh:xxxh respectively). Now inside your project res folder you have to create 4 folder with dimens file e.g.

  1. res/values-hdpi/dimens.xml
  2. res/values-xhdpi/dimens.xml
  3. res/values-xxhdpi/dimens.xml
  4. res/values-xxxhdpi/dimens.xml

Now inside dimens.xml file you have to place text sizes. I am showing you code for values-hdpi, similarly you have to place code for other resolution values/dimens.xml file.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <dimen name="text_size">4px</dimen>
</resources>

For other resolutions it is like xhdpi : 6px, xxhdpi : 8px, xxxhdpi : 12px. This is calculated with the ratio (3:4:6:8:12) I have written above. Lets discuss other text size example with above ratio. If you want to take text size of 12px in hdpi, then in other resolution it would be

  1. hdpi : 12px
  2. xhdpi : 18px
  3. xxhdpi : 24px
  4. xxxhdpi : 36px

This is the simple solution to implement required text size for all resolutions. I am not considering values-mdpi resolution devices here. If any one want to include text size for this resolution then ration is like 3:4:6:8:12. In any query please let me know. Hope it will help you people out.


Sometimes, it's better to have only three options

 style="@android:style/TextAppearance.Small"

Use small and large to differentiate from normal screen size.

<TextView
            android:id="@+id/TextViewTopBarTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@android:style/TextAppearance.Small"/>

For normal, you don't have to specify anything.

<TextView
            android:id="@+id/TextViewTopBarTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

Using this, you can avoid testing and specifying dimensions for different screen sizes.


I did same by dimension and paint something like (with dp but only for text and in drawText())

XML:

   <dimen name="text_size">30sp</dimen>

Code:

   Paint p =new Paint();
       p.setTextSize(getResources().getDimension(R.dimen.text_Size));

To unify all of the screens to show same element sizes including font size: - Design the UI on one screen size with whatever sizes you find appropriate during the design i.e. TextView font size is 14dp on default screen size with 4'6 inches.

  • Programmatically calculate the physical screen size of the other phones i.e. 5'2 inches of other phones/screens.

  • Use a formula to calculate the percentage difference between the 2 screens. i.e. what's the % difference between 4'6 and 5'2.

  • Calculate the pixel difference between the 2 TextViews based on the above formula.

  • Get the actual size (in pixels) of the TextView font-size and apply the pixels difference (you calculated earlier) to the default font-size.

With this way you can apply dynamic aspect ratio to all of screen sizes and the result is great. You'll have identical layout and sizes on each screen.

It can be a bit tricky at first but totally achieves the goal once you figure the formula out. With this method you don't need to make multiple layouts just to fit different screen sizes.


You can also use weightSum and layout_weight property to adjust your different screen.

For that, you have to make android:layout_width = 0dp, and android:layout_width = (whatever you want);


Do not hardcode the sizes.

For flexibility ad new screen resolutions - the best practice is to place dummy TextView into layout to obtain the textSize:

<TextView
        android:id="@+id/dummyTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:text="TextView" />

And in your code for example:

TextView testTextView = (TextView) rootView.findViewById(R.id.dummyTextView);
float textSize = testTextView.getTextSize();

Keep textSize as a reference to which you can add constant or percetage size (by calculating).


Everyone can use the below mentioned android library that is the easiest way to make text sizes compatible with almost all devices screens. It actually developed on the basis of new android configuration qualifiers for screen size (introduced in Android 3.2) SmallestWidth swdp.

https://github.com/intuit/sdp