I have a vertical LinearLayout
with two TextView
inside it. The former contains a static text property (it\'s text never change) and the last conta
If you set includeFontPadding to false it helps.
android:includeFontPadding="false"
but if you know you don't have any descenders because you set
android:textAllCaps="true"
or you know there are no characters which have descender, you can make a custom TextView and set the height to the baseline.
public class ExTextView extends TextView {
public ExTextView(Context context) {
this(context, null);
}
public ExTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ExTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ExTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onDraw(Canvas canvas) {
setHeight(getBaseline()); // <--- Shrink size to baseline
super.onDraw(canvas);
}
}
The source code is included in my UiComponents test app. https://github.com/landenlabs/UiComponents
Since my requirement is override the existing textView get from findViewById(getResources().getIdentifier("xxx", "id", "android"));
, so I can't simply try onDraw()
of other answer.
But I just figure out the correct steps to fixed my problem, here is the final result from Layout Inspector:
Since what I wanted is merely remove the top spaces, so I don't have to choose other font to remove bottom spaces.
Here is the critical code to fixed it:
Typeface mfont = Typeface.createFromAsset(getResources().getAssets(), "fonts/myCustomFont.otf");
myTextView.setTypeface(mfont);
myTextView.setPadding(0, 0, 0, 0);
myTextView.setIncludeFontPadding(false);
The first key is set custom font "fonts/myCustomFont.otf" which has the space on bottom but not on the top, you can easily figure out this by open otf file and click any font in android Studio:
As you can see, the cursor on the bottom has extra spacing but not on the top, so it fixed my problem.
The second key is you can't simply skip any of the code, otherwise it might not works. That's the reason you can found some people comment that an answer is working and some other people comment that it's not working.
Let's illustrated what will happen if I remove one of them.
Without setTypeface(mfont);
:
Without setPadding(0, 0, 0, 0);
:
Without setIncludeFontPadding(false);
:
Without 3 of them (i.e. the original):
By default, a TextView includes some padding to leave space for accent characters. You can turn that off with:
android:includeFontPadding="false"
or
textView.setIncludeFontPadding(false)
negative margins will do the trick
you should change the height of TextView and maybe change android:gravity="bottom"
height is between textsize and size of textView with Wrapcontent.
public class MyTextViewBounder extends TextView {
public MyTextViewBounder(Context context) {
super(context);
}
public MyTextViewBounder(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextViewBounder(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//test kích thước thực tế với kích thước của Textview bao quanh text của nó như thế nào
int width, height;
Paint iPaint;
Rect iRect = new Rect();
iPaint = new Paint();
iPaint.setTextSize(13);
iPaint.setTextAlign(Paint.Align.CENTER);
//call below code outsite
//this.setText("Hung");
//this.setTextSize(TypedValue.COMPLEX_UNIT_PX,13);
//this..setIncludeFontPadding(false); //height from 18px down to 15px
iPaint.getTextBounds("Hung",0,4,iRect); //width = 34px, height = 12px
width = this.getWidth(); //= 30px
height = this.getHeight(); //= 18px
width = this.getMeasuredWidth(); //=30px
height = this.getMeasuredHeight(); //= 18px
width = iRect.width(); //34px
height = iRect.height(); //12 px
}
}
Make baseline of the text equal to the bottom of the TextView.
public class BaselineTextView extends TextView {
public BaselineTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
int yOffset = getHeight() - getBaseline();
canvas.translate(0, yOffset);
super.onDraw(canvas);
}
}
NOTE: To avoid chopping off descenders call setClipChildren(false)
on your TextView
's parent ViewGroup
(android:clipChildren="false"
in XML).