Android Textview Justify Text

Android TextView Justify Text

I do not believe Android supports full justification.

UPDATE 2018-01-01: Android 8.0+ supports justification modes with TextView.

Justifying text inside a TextView in android

So, after looking a bit more at this: https://github.com/ufo22940268/android-justifiedtextview and TextView in general, I discovered that my main problem was my approach.

Using the approach of scaling the width of the " " characters was sound in theory, but after doing so, the width of the line changes again, as it seems that the width of the line is NOT the sum of its parts.

I have changed my approach and took inspiration from the link above, and so in my new approach I draw each character by itself, instead of drawing the whole line. If the text needs to be justified (based on a custom "justify" boolean attribute) then it will draw the line and justify it, else it will just draw the line.

Edit: I have changed the code now so that it also supports RTL texts. I will upload the code somewhere in the next few days.

Here's the result:
justify textview

Here's the code:

public class DTextView extends AppCompatTextView {


private boolean justify;
private float textAreaWidth;
private float spaceCharSize;
private float lineY;

public DTextView(Context context) {
super(context);
}

public DTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}

public DTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}

/**
* @param attrs the attributes from the xml
* This function loads all the parameters from the xml
*/
private void init(AttributeSet attrs) {

TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.DTextView, 0, 0);

justify = ta.getBoolean(R.styleable.DTextView_justify, false);

ta.recycle();
}

@Override
protected void onDraw(Canvas canvas) {
drawText(canvas);
}

private void drawText(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
textAreaWidth = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight());

spaceCharSize = paint.measureText(" ");

String text = getText().toString();
lineY = getTextSize();

Layout textLayout = getLayout();

if (textLayout == null)
return;

Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) Math.ceil(fm.descent - fm.ascent);
textHeight = (int) (textHeight * getLineSpacingMultiplier() + textLayout.getSpacingAdd());

for (int i = 0; i < textLayout.getLineCount(); i++) {

int lineStart = textLayout.getLineStart(i);
int lineEnd = textLayout.getLineEnd(i);

float lineWidth = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, paint);
String line = text.substring(lineStart, lineEnd);

if (line.charAt(line.length() - 1) == ' ') {
line = line.substring(0, line.length() - 1);
}

if (justify && i < textLayout.getLineCount() - 1) {
drawLineJustified(canvas, line, lineWidth);
} else {
canvas.drawText(line, 0, lineY, paint);
}

lineY += textHeight;
}

}

private void drawLineJustified(Canvas canvas, String line, float lineWidth) {
TextPaint paint = getPaint();

float emptySpace = textAreaWidth - lineWidth;
int spaces = line.split(" ").length - 1;
float newSpaceSize = (emptySpace / spaces) + spaceCharSize;

float charX = 0;

for (int i = 0; i < line.length(); i++) {
String character = String.valueOf(line.charAt(i));
float charWidth = StaticLayout.getDesiredWidth(character, paint);
if (!character.equals(" ")) {
canvas.drawText(character, charX, lineY, paint);
}

if (character.equals(" ") && i != line.length() - 1)
charX += newSpaceSize;
else
charX += charWidth;
}

}
}

and the XML:

<il.co.drapp.views.text.DTextView
android:layout_width="match_parent"
android:inputType="textMultiLine|textNoSuggestions"
app:justify="true"
android:id="@+id/justifyText"
android:text="@string/article_dummy_text"
android:layout_height="wrap_content" />

Thanks to Aditya Vyas-Lakhan for the links

How to justify text of TextView in Android

XML Layout: declare WebView instead of TextView

<WebView
android:id="@+id/textContent"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

Java code: set text data to WebView

WebView view = (WebView) findViewById(R.id.textContent);
String text;
text = "<html><body><p align=\"justify\">";
text+= "This is the text will be justified when displayed!!!";
text+= "</p></body></html>";
view.loadData(text, "text/html", "utf-8");

This may Solve your problem.

Right align text in android TextView

I think that you are doing this: android:layout_width = "wrap_content"

If this is the case, do this: android:layout_width = "match_parent"

TextView text justification

the attribute "justificationMode" only works on android running API version 26 or higher

Use this library to justify text on android running lower than API 26

You can also use this library it has the most stars on GitHub for text justification in android



Related Topics



Leave a reply



Submit