43

How to align the text to top of a TextView?
Equivalent Android API for Swings setInsets()?
that is top of text should start be in (0,0) of TextView

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical">

    <TextView 
        android:id="@+id/text1" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="TextView" 
        android:textSize="42sp" 
        android:paddingTop="0px" 
        android:gravity="top">
    </TextView> 
</LinearLayout> 

I have used above snippet, however still output is not as expected
Any ideas?

Jeremy Logan
  • 45,614
  • 37
  • 119
  • 143
Riyaz Mohammed Ibrahim
  • 9,297
  • 5
  • 24
  • 33

6 Answers6

71

So the space at the top of the TextView is padding used for characters outside the English language such as accents. To remove this space you can either set the android:includeFontPadding attribute to false in your XML or you can do it programmatically with the function setIncludeFontPadding(false).

Look at the SDK documentation for TextView if this is still unclear.

EDITED ANSWER
If setting the android:includeFontPadding attribute does not accomplish what you're trying to do, the other solution is to override the onDraw(Canvas canvas) method of the TextView that you're using so that it eliminates the additional top padding that Android adds to every TextView. After writing my original answer, I noticed that for some reason TextView includes extra padding in addition to the font padding. Removing the font padding as well as this additional padding perfectly aligns the text to the top of the TextView. Look at the code snippet below.

public class TopAlignedTextView extends TextView {

    // Default constructor when inflating from XML file
    public TopAlignedTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    // Default constructor override
    public TopAlignedTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs);
        setIncludeFontPadding(false); //remove the font padding
        setGravity(getGravity() | Gravity.TOP); //make sure that the gravity is set to the top
    }

    /*This is where the magic happens*/
    @Override
    protected void onDraw(Canvas canvas){
        TextPaint textPaint = getPaint(); 
        textPaint.setColor(getCurrentTextColor());
        textPaint.drawableState = getDrawableState();
        canvas.save();

        //converts 5dip into pixels            
        int additionalPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getContext().getResources().getDisplayMetrics());

        //subtracts the additional padding from the top of the canvas that textview draws to in order to align it with the top.            
        canvas.translate(0, -additionalPadding);
        if(getLayout() != null)
            getLayout().draw(canvas);
        canvas.restore();
    }
} 
Xavi Rigau
  • 1,295
  • 12
  • 17
Kachi
  • 3,539
  • 2
  • 21
  • 17
  • 21
    This really doesn't work. The 5 pixel subtraction seems to be completely arbitrary. For sufficiently small text sizes, the text will clip with the edge of the view. For larger text sizes, the annoying extra padding will remain. – Kyle Ivey Aug 21 '13 at 02:17
  • Very interesting.. i did not used it but i mark a favourite answer, could be usefull. – Adam Varhegyi Dec 02 '13 at 17:32
20

In your .xml, write that:

android:gravity="center|top"

The first "center" align your line horizontally in the center and the next "top" align vertically up.

Terranology
  • 588
  • 8
  • 15
18

The actual font itself has extra whitespace on the top and bottom I believe.

Usually what I do is give the view negative margins. The issue is that this looks bad when devices come with different fonts.

android:layout_marginTop="-5dp"
android:layout_marginBottom="-5dp"

You will have to adjust based on the text size, bigger text sizes require more negative padding.

Community
  • 1
  • 1
Ryan
  • 23
  • 1
  • 7
  • When using custom fonts, after testing many options like includeFontPadding, lineSpacingExtra and lineSpacingMultiplier to remove top and bottom font spaces, this method is the only one that worked. Too bad that i need to create a style for every font size used. – Gero Nov 21 '13 at 15:33
2

Possible, you do not need make your view based on TextView. Try to extend View and write your text in onDraw().

Look at here: https://stackoverflow.com/a/32081250/1263771

Community
  • 1
  • 1
tse
  • 4,787
  • 2
  • 33
  • 54
1

I think your snippet is right. I guess you are bothered by some pixels between top of the letter "T" and top edge of the TextView? This space is required to render some letters that are not present in English alphabet.

Check that links to get idea:

alex2k8
  • 39,732
  • 56
  • 158
  • 214
0

Im not sure if i understand what you are meaning, but the text inside the textview is going to be align to the top if you use gravity=top on the text-view.

If you put a backgrund color on you textview you might see better what is happening...

I guess you problem is that the textview is centered since you use fill_parent on both height and width on the parent LinearLayout. The textview seems to be the only child so try putting gravity=top on the LinearLayout...

Thats the only thing i could think of...

Vidar Vestnes
  • 41,116
  • 28
  • 81
  • 97