So, wie die meisten von Ihnen wissen, gibt es keinen Text in einem TextView in Android rechtfertigen. Also habe ich eine benutzerdefinierte Textansicht erstellt, um das Problem zu umgehen. Aus irgendeinem Grund brechen jedoch manchmal bei einigen Geräten Interpunktionszeichen die Zeile aus irgendeinem Grund. Ich habe auf einem LG G3 und Emulator (Nexus 4 mit der neuesten Version) getestet und ein Komma "," zum Beispiel bricht die Begründung auf dem LG G3, aber nicht auf dem Emulator.Rechtfertigung von Text in einem TextView in Android
Wenn ich einen Padding Anfang und Ende (oder links und rechts) von mindestens 2 hinzufügen, ist das Problem gelöst. Das sieht mir sehr willkürlich aus.
Im Grunde war meine Logik, dass, um den Text zu rechtfertigen, ich die Breite des TextView selbst kennen müsste, konstruiere den Text in Zeilen, die maximal diese Länge haben. Dann, indem Sie die Anzahl der Leerzeichen in der Zeile und den verbleibenden leeren Platz finden, strecken Sie die Zeichen "" (Leerzeichen), die entsprechend den verbleibenden Pixeln (oder dem Platz in der Ansicht) skaliert werden sollen.
Es funktioniert fast perfekt, und die meiste Zeit unterstützt es auch RTL-Text.
here're einige Bilder des Textes (eine einfache lorem impsum) mit und ohne die störenden Markierungen (erste ist 4 auf Emulator nexus läuft 7.1.1, zweite ist auf LG G3 läuft v5.0)
Hier ist der Code:
public class DTextView extends AppCompatTextView {
private boolean justify;
public DTextView(Context context) {
super(context);
}
public DTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public DTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void setJustify(boolean justify) {
this.justify = justify;
if (justify) {
justify();
}
}
private void init(@Nullable AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.DTextView, 0, 0);
justify = ta.getBoolean(R.styleable.DTextView_justify, false);
ta.recycle();
}
private SpannableStringBuilder justifyText() {
String[] words = getText().toString().split(" ");
setText("");
int maxLineWidth = getWidth() - getPaddingLeft() - getPaddingRight();
SpannableStringBuilder justifiedTextSpannable = new SpannableStringBuilder();
//This will build the new text with the lines rearranged so that they will have a width
//bigger than the View's own width
ArrayList<String> lines = new ArrayList<>(0);
String line = "";
for (String word : words) {
if (getWordWidth(line + word) < maxLineWidth) {
line += word + " ";
} else {
line = line.substring(0, line.length() - 1);
lines.add(line);
line = word + " ";
}
}
//Add the last line
lines.add(line);
for (int i = 0; i < lines.size() - 1; i++) {
justifiedTextSpannable.append(justifyLine(lines.get(i), maxLineWidth));
justifiedTextSpannable.append("\n");
}
justifiedTextSpannable.append(lines.get(lines.size() - 1));
return justifiedTextSpannable;
}
private SpannableString justifyLine(String line, float maxWidth) {
SpannableString sLine = new SpannableString(line);
float spaces = line.split(" ").length - 1;
float spaceCharSize = getWordWidth(" ");
float emptySpace = maxWidth - getWordWidth(line);
float newSpaceSize = (emptySpace/spaces) + spaceCharSize;
float scaleX = newSpaceSize/spaceCharSize;
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) == ' ') {
sLine.setSpan(new ScaleXSpan(scaleX), i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return sLine;
}
private void justify() {
justify = false;
setText(justifyText());
invalidate();
}
private float getWordWidth(String word) {
return getPaint().measureText(word);
}
@Override
protected void onDraw(Canvas canvas) {
if (!justify)
super.onDraw(canvas);
else
justify();
}
}
ich würde es sehr schätzen jemand, der etwas Licht auf diesem verschütten kann.
ist es gelöst oder nicht –
ja, ich habe es selbst gelöst und es markiert als basierend auf einen der Links gelöst Sie gab. Schrieb es in der Antwort natürlich. – ShayR