This is what happens in the preview and on device:
TextView is nothing special, it just loads the custom font:
public class TestTextView extends AppCompatTextView {
public TestTextView(Context context) {
super(context);
init(context);
}
public TestTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public TestTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
void init(Context context) {
Typeface t = Typeface.createFromAsset(context.getAssets(), "fonts/daisy.ttf");
setTypeface(t);
}
}
Layout is also very basic, but just in case:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/material_red200"
android:orientation="vertical">
<*custompackage* .TestTextView
android:gravity="left"
android:padding="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="just some text for testing"
android:textColor="@color/material_black"
android:textSize="100dp" />
</LinearLayout>
As you can see, the left parts, like 'j' and 'f' are cut off.
Setting the padding or margin did not work.
This font fits into it's frame when using from other programs.
Thanks in advance.
Edit: What @play_err_ mentioned is not a solution in my case.
I am also loading different fonts dynamically and I do not want to create an
if(badfont)
addSpaces()
This answer has led me to the right path: https://stackoverflow.com/a/28625166/4420543
So, the solution is to create a custom Textview and override the onDraw method:
@Override
protected void onDraw(Canvas canvas) {
final Paint paint = getPaint();
final int color = paint.getColor();
// Draw what you have to in transparent
// This has to be drawn, otherwise getting values from layout throws exceptions
setTextColor(Color.TRANSPARENT);
super.onDraw(canvas);
// setTextColor invalidates the view and causes an endless cycle
paint.setColor(color);
System.out.println("Drawing text info:");
Layout layout = getLayout();
String text = getText().toString();
for (int i = 0; i < layout.getLineCount(); i++) {
final int start = layout.getLineStart(i);
final int end = layout.getLineEnd(i);
String line = text.substring(start, end);
System.out.println("Line:\t" + line);
final float left = layout.getLineLeft(i);
final int baseLine = layout.getLineBaseline(i);
canvas.drawText(line,
left + getTotalPaddingLeft(),
// The text will not be clipped anymore
// You can add a padding here too, faster than string string concatenation
baseLine + getTotalPaddingTop(),
getPaint());
}
}
I have encountered the same problem and i found a one liner solution for thouse who are not using the TextView.shadowLayer
.
this is based on the source code that [Dmitry Kopytov] brought here:
editTextOrTextView.setShadowLayer(editTextOrTextView.textSize, 0f, 0f, Color.TRANSPARENT)
that's it, now the canvas.clipRect
in TextView.onDraw()
won't cut off the curly font sides.
I encountered the same problem when I used some fonts in EditText
.
My first attempt was to use padding. Size of view increased but text is still cropped.
Then I looked at the source code TextView
. In method onDraw
method Canvas.clipRect
is called to perform this crop.
My solution to bypass cropping when use padding :
1) Сreate custom class inherited from Canvas
and override method clipRect
public class NonClippableCanvas extends Canvas {
public NonClippableCanvas(@NonNull Bitmap bitmap) {
super(bitmap);
}
@Override
public boolean clipRect(float left, float top, float right, float bottom) {
return true;
}
}
2) Create custom TextView
and override methods onSizeChanged
and onDraw
.
In the method onSizeChanged
create bitmap and canvas.
In the method onDraw
draw on bitmap by passing our custom Canvas
to method super.onDraw
. Next, draw this bitmap on the target canvas.
public class CustomTextView extends AppCompatTextView {
private Bitmap _bitmap;
private NonClippableCanvas _canvas;
@Override
protected void onSizeChanged(final int width, final int height,
final int oldwidth, final int oldheight) {
if (width != oldwidth || height != oldheight) {
_bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
_canvas = new NonClippableCanvas(_bitmap);
}
super.onSizeChanged(width, height, oldwidth, oldheight);
}
@Override
protected void onDraw(Canvas canvas) {
_canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
super.onDraw(_canvas);
canvas.drawBitmap(_bitmap, 0, 0, null);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With