Android TextView Text ausrichten

396

Wie erhalten Sie den Text eines TextViewzu begründenden Textes (mit bündigem Text auf der linken und rechten Seite)?

Ich habe hier eine mögliche Lösung gefunden , aber sie funktioniert nicht (selbst wenn Sie vertikal-center in center_vertical usw. ändern).

Bill die Eidechse
quelle
@ Jimbo Antwort ist richtig funktioniert definitiv für meinen Fall auf Eingabetext und Textansicht für Sprache Arabisch von rechts nach links Eingabe und Anzeige, aber für Eingabetext musste ich auch Schwerkraft = "rechts"
hinzufügen
Sie können github.com/pouriaHemmati/JustifiedTextView
Pouria Hemati

Antworten:

239

Ich glaube nicht, dass Android die vollständige Rechtfertigung unterstützt.

UPDATE 2018-01-01 : Android 8.0+ unterstützt Ausrichtungsmodi mitTextView .

CommonsWare
quelle
5
Bei weiterer Analyse könnten Sie android :vity = "fill_horizontal" einen Schuss geben. Das wird als "Vergrößern Sie die horizontale Größe des Objekts, falls erforderlich, damit es seinen Container vollständig ausfüllt" beschrieben, aber ich weiß nicht, wie sie den Text "vergrößern".
CommonsWare
8
android :vity = "fill_horizontal" hat auch nicht funktioniert. Es sieht so aus, als ob Android die Rechtfertigung doch nicht unterstützt,
6
Nein, Sie können die Eigenschaft nicht wie die Schwerkraft einstellen. Sie können die Ausrichtung jedoch auf Ihren Text festlegen, indem Sie die Webansicht anstelle der Textansicht verwenden. Sie können sich auf seal.io/2010/12/only-way-how-to-align-text-in-block-in.html beziehen . (Von stackoverflow.com/questions/5976627/… gestohlen )
jcaruso
2
@CommonsWare Gibt es nun eine richtige Möglichkeit, Text zu rechtfertigen?
John R
1
Mann, ich lebe mit einer starken Webansicht, um dies zu erreichen, und glauben Sie mir, meine Benutzeroberfläche verlangt nach neuen Dingen, die noch nicht zur API hinzugefügt wurden, da es für Komponenten wie Chat in einer Listenansicht verdammt langsam ist.
nobalG
156

Die @ CommonsWare-Antwort ist korrekt. Android 8.0+ unterstützt "Vollständige Rechtfertigung" (oder einfach "Rechtfertigung", wie es manchmal mehrdeutig bezeichnet wird).

Android unterstützt auch "Flush Left / Right Text Alignment". Zur Unterscheidung siehe den Wikipedia-Artikel zur Begründung . Viele Menschen betrachten das Konzept der „Rechtfertigung“ als eine vollständige Rechtfertigung sowie eine Ausrichtung von links / rechts, nach der sie am Ende suchen, wenn sie eine Ausrichtung von links / rechts durchführen möchten. Diese Antwort erklärt, wie die Ausrichtung von links / rechts erreicht wird.

Es ist möglich, die Ausrichtung von links / rechts spülen zu erreichen (im Gegensatz zur vollständigen Begründung, nach der die Frage gestellt wird). Zur Veranschaulichung verwende ich als Beispiel ein einfaches zweispaltiges Formular (Beschriftungen in der linken Spalte und Textfelder in der rechten Spalte). In diesem Beispiel wird der Text in den Beschriftungen in der linken Spalte rechtsbündig ausgerichtet, sodass sie bündig mit ihren Textfeldern in der rechten Spalte angezeigt werden.

Im XML-Layout können Sie die TextView-Elemente selbst (linke Spalte) nach rechts ausrichten, indem Sie in allen TextViews das folgende Attribut hinzufügen:

<TextView
   ...
   android:layout_gravity="center_vertical|end">
   ...
</TextView>

Wenn der Text jedoch in mehrere Zeilen eingeschlossen wird, wird der Text in der Textansicht immer noch bündig linksbündig ausgerichtet. Durch Hinzufügen des folgenden Attributs wird der tatsächliche Text in der Textansicht rechtsbündig (links) ausgerichtet:

<TextView
   ...
   android:gravity="end">
   ...
</TextView>

Das Gravity- Attribut gibt also an, wie der Text in TextView ausgerichtet werden soll. Layout_gravity gibt an, wie das TextView-Element selbst ausgerichtet / gestaltet werden soll.

plainjimbo
quelle
12
Wenn ich das richtig verstehe und die Testergebnisse habe, muss der Text nur links oder rechts ausgerichtet werden. Das rechtfertigt den Text nicht, oder?
Paul Lammertsma
14
Ausgezeichnet. Nur um hinzuzufügen, wenn Sie eine zentrale Ausrichtung wünschen, können Sie dies tun android:layout_gravity="center_horizontal|center" android:gravity="center".
Luis A. Florit
Ich arbeite definitiv für meinen Fall an Eingabetext und Textansicht für die arabische Sprache von rechts nach links. Eingabe und Anzeige
shareef
1
Dies ist nur Ausrichtung, keine Rechtfertigung. Lesen Sie diesen Wikipedia-Link sorgfältig durch. Der Unterschied zwischen den verschiedenen Begründungsarten betrifft nur die letzte Zeile eines Absatzes. Es gibt keine Links / Rechts / Mittel-Ausrichtung für Absätze, die nur eine Zeile haben.
Karu
warum dann überhaupt hier antworten, wenn es nicht darum gehtjustify
user924
136

Um Text in Android zu rechtfertigen, habe ich WebView verwendet

    setContentView(R.layout.main);

    WebView view = new WebView(this);
    view.setVerticalScrollBarEnabled(false);

    ((LinearLayout)findViewById(R.id.inset_web_view)).addView(view);

    view.loadData(getString(R.string.hello), "text/html; charset=utf-8", "utf-8");

und html.

<string name="hello">
<![CDATA[
<html>
 <head></head>
 <body style="text-align:justify;color:gray;background-color:black;">
  Lorem ipsum dolor sit amet, consectetur 
  adipiscing elit. Nunc pellentesque, urna
  nec hendrerit pellentesque, risus massa
 </body>
</html>
]]>
</string>

Ich kann noch keine Bilder hochladen, um dies zu beweisen, aber "es funktioniert für mich".

Konrad Nowicki
quelle
3
Schöne Lösung hier. FWIW Sie brauchen nicht den größten Teil des zusätzlichen HTML. Das Body-Tag mit Textausrichtung reicht aus.
Gnac
5
Das funktioniert gut. Beachten Sie , dass der Hintergrund transparent , indem Sie machen view.loadData()mit view.setBackgroundColor("#00000000").
Paul Lammertsma
Es ist mir jedoch nicht gelungen, eine benutzerdefinierte Schriftart zu laden. Ich habe dies und diesen Vorschlag ohne Glück versucht .
Paul Lammertsma
2
Wie ich in diesen Threads erwähnt habe, habe ich eine Lösung gefunden: Wenn Sie eine HTML-Datei erstellen und in die Assets einfügen, laden Sie sie über view.loadUrl()Works, während view.loadData()dies nicht der Fall ist. Ich habe keine Ahnung, warum letzteres nicht.
Paul Lammertsma
1
@PaulLammertsma, setBackgroundColor (0x00000000) wäre eher das richtige Format zum Festlegen des transparenten Hintergrunds.
Richey
100

AKTUALISIERT

Wir haben dafür eine einfache Klasse erstellt. Derzeit gibt es zwei Methoden, um das zu erreichen, wonach Sie suchen. Beide erfordern KEIN WEBVIEW und UNTERSTÜTZEN SPANNABLES .

BIBLIOTHEK : https://github.com/bluejamesbond/TextJustify-Android

UNTERSTÜTZUNG : Android 2.0 bis 5.X.

INSTALLIEREN

// Please visit Github for latest setup instructions.

BILDSCHIRMFOTO

Comparison.png

Mathew Kurian
quelle
Ist eine echte Hilfe, aber wenn ich es verwende, behalten meine TextViews nicht das ursprüngliche Format bei. Ich verweise: Ränder, Textstil, und ich denke, dass auch die Textgröße, Plese arbeitet weiter daran, eine wirklich große Hilfe sein sollte
Leonardo Sapuy
Nun, ich kann diese Klassen nicht etablieren. einer von ihnen hatte keinen Paketnamen, der andere gibt einen gelben Fehler aus. Eigentlich kann ich nicht vertrauen.
Mehmet
Schöne Bibliothek, aber ich weiß immer noch nicht, wie ich mit dieser Bibliothek Formatierungen zum Text hinzufügen soll.
Semanticer
4
Vielen Dank für diese großartige gemeinsam genutzte Bibliothek, die jedoch keinen persischen oder arabischen Text unterstützt. Wenn ich die Richtung festlege, wird mein Wort vom letzten zum Anfang gezogen, anstatt vom letzten zum letzten. Ich meine das: Mein Wort ist: "سلام" und seine Auslosung lautet: "مالس". (Wenn Sie Persisch nicht verstehen, sehen Sie dieses Beispiel: Lassen Sie mich "1234" -> "4321")
Naruto Uzumaki
1
Basierend auf scrollView ... Schöne Lösung, kann aber noch keine Antwort finden, die es mit Textansicht möglich macht. :(
SuperUser
88

TextViewin Android Obietet vollständige Begründung (neue typografische Ausrichtung) selbst.

Sie müssen nur Folgendes tun:

Kotlin

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    textView.justificationMode = JUSTIFICATION_MODE_INTER_WORD
}

Java

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    textView.setJustificationMode(JUSTIFICATION_MODE_INTER_WORD);
}

Standard ist JUSTIFICATION_MODE_NONE.

Jaydipsinh Zala
quelle
3
Hoffen wir, dass es zurück in die Support-Bibliothek portiert wird, dann O :)
Stefan Haustein
2
Bitte fügen Sie hier Bibliothek hinzu !!
Kunal Dharaiya
4
Wie kann man die Verwendung von XML rechtfertigen?
Vikash Parajuli
14
Sie können android: justificationMode = "inter_word" in XML verwenden.
Christian D
5
API 26 für Android erforderlich: justificationMode.
Bink
42

Sie können JustifiedTextView für Android- Projekte in Github verwenden. Dies ist eine benutzerdefinierte Ansicht, die für Sie gerechtfertigten Text simuliert. Es unterstützt Android 2.0+ und Sprachen von rechts nach links. Geben Sie hier die Bildbeschreibung ein

Saeed Zarinfam
quelle
Es unterstützt keine spannbare Zeichenfolge
MSepehr
Wie können wir unseren eigenen Text hinzufügen?
Karan
Bitte sehen Sie das Beispiel auf Github.
Saeed Zarinfam
Hallo Saeed, tnx für deine Hilfe, gibt es eine Möglichkeit, spannbare Textansichten zu unterstützen?!
Hamid Reza
@SaeedZarinfam Ich habe versucht , „JustifiedTextView für Android“ zu verwenden , aber ich habe Fehler auf dem XML - Tag ir.noghteh.JustifiedTextView würde u plz mir zu helfen , zu dieser Frage stackoverflow.com/questions/37911376/...
Jumong
30

Ich schreibe eine Widget-Basis auf nativer Textansicht, um dies zu tun.

Github

Frank Cheng
quelle
Ich hatte dieses empfohlen, vor allem, weil es auf der ursprünglichen Textansicht des offiziellen Android SDK basiert. Meiner persönlichen Meinung nach ist es viel leichter als die Technik der Webansicht, die viele Leute zu diesem allgemeinen Thema veröffentlichen. Wenn Sie eine App erstellen, die speichertechnisch sein muss, z. B. mithilfe von Listenansichtsobjekten, können Sie die Verwendung dieser Option in Betracht ziehen. Ï Probieren Sie es bereits aus und es funktioniert wie erwartet. Wenn Sie einen anderen besser kennen, wie diesen 1, teilen Sie mir bitte Ihre Erfahrungen mit.
SuperUser
Gute Arbeit übrigens. Was ich gesucht habe.
SuperUser
5
unterstützt keine RTL-Sprachen wie Persisch
Feuer im Loch
1
@ Frank Cheng Sehr nützliche Bibliothek. Ich bekomme am Ende des Absatzes viele Leerzeichen. Wie kann ich es reparieren?
iSrinivasan27
1
hat bei mir funktioniert, aber die letzte Zeile der Textansicht wurde abgeschnitten. Ich musste 5 für die Textansicht weiter auffüllen.
TharakaNirmana
23

Ich habe einen Weg gefunden, um dieses Problem zu lösen, aber das mag nicht sehr anmutig sein, aber der Effekt ist nicht schlecht.

Das Prinzip besteht darin, die Leerzeichen jeder Zeile durch ImageSpan mit fester Breite zu ersetzen (die Farbe ist transparent).

public static void justify(final TextView textView) {

    final AtomicBoolean isJustify = new AtomicBoolean(false);

    final String textString = textView.getText().toString();

    final TextPaint textPaint = textView.getPaint();

    final SpannableStringBuilder builder = new SpannableStringBuilder();

    textView.post(new Runnable() {
        @Override
        public void run() {

            if (!isJustify.get()) {

                final int lineCount = textView.getLineCount();
                final int textViewWidth = textView.getWidth();

                for (int i = 0; i < lineCount; i++) {

                    int lineStart = textView.getLayout().getLineStart(i);
                    int lineEnd = textView.getLayout().getLineEnd(i);

                    String lineString = textString.substring(lineStart, lineEnd);

                    if (i == lineCount - 1) {
                        builder.append(new SpannableString(lineString));
                        break;
                    }

                    String trimSpaceText = lineString.trim();
                    String removeSpaceText = lineString.replaceAll(" ", "");

                    float removeSpaceWidth = textPaint.measureText(removeSpaceText);
                    float spaceCount = trimSpaceText.length() - removeSpaceText.length();

                    float eachSpaceWidth = (textViewWidth - removeSpaceWidth) / spaceCount;

                    SpannableString spannableString = new SpannableString(lineString);
                    for (int j = 0; j < trimSpaceText.length(); j++) {
                        char c = trimSpaceText.charAt(j);
                        if (c == ' ') {
                            Drawable drawable = new ColorDrawable(0x00ffffff);
                            drawable.setBounds(0, 0, (int) eachSpaceWidth, 0);
                            ImageSpan span = new ImageSpan(drawable);
                            spannableString.setSpan(span, j, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }
                    }

                    builder.append(spannableString);
                }

                textView.setText(builder);
                isJustify.set(true);
            }
        }
    });
}

Ich habe den Code auf GitHub gestellt: https://github.com/twiceyuan/TextJustification

Überblick:

Überblick

zweimal Yuan
quelle
1
Funktioniert nicht in der XML-Vorschau, funktioniert aber hervorragend mit einem echten Gerät :)
pgreze
15

XML-Layout: Deklarieren Sie WebView anstelle von TextView

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

Java-Code: Setzen Sie Textdaten auf 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");

Dies kann Ihr Problem lösen. Es hat voll für mich funktioniert.


quelle
9

Hier ist, wie ich es gemacht habe, ich denke, die eleganteste Art, die ich konnte. Mit dieser Lösung müssen Sie in Ihren Layouts nur Folgendes tun:

  • Fügen Sie eine zusätzliche xmlnsErklärung hinzu
  • Ändern Sie Ihren TextViewQuelltext-Namespace von Android in Ihren neuen Namespace
  • Ersetzen Sie Ihr TextViews durchx.y.z.JustifiedTextView

Hier ist der Code. Funktioniert einwandfrei auf meinen Handys (Galaxy Nexus Android 4.0.2, Galaxy Teos Android 2.1). Fühlen Sie sich natürlich frei, meinen Paketnamen durch Ihren zu ersetzen.

/assets/justified_textview.css :

body {
    font-size: 1.0em;
    color: rgb(180,180,180);
    text-align: justify;
}

@media screen and (-webkit-device-pixel-ratio: 1.5) {
    /* CSS for high-density screens */
    body {
        font-size: 1.05em;
    }
}

@media screen and (-webkit-device-pixel-ratio: 2.0) {
    /* CSS for extra high-density screens */
    body {
        font-size: 1.1em;
    }
}

/res/values/attrs.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="JustifiedTextView">
        <attr name="text" format="reference" />
    </declare-styleable>
</resources>

/res/layout/test.xml :

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:myapp="http://schemas.android.com/apk/res/net.bicou.myapp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <net.bicou.myapp.widget.JustifiedTextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            myapp:text="@string/surv1_1" />

    </LinearLayout>
</ScrollView>

/src/net/bicou/myapp/widget/JustifiedTextView.java :

package net.bicou.myapp.widget;

import net.bicou.myapp.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.webkit.WebView;

public class JustifiedTextView extends WebView {
    public JustifiedTextView(final Context context) {
        this(context, null, 0);
    }

    public JustifiedTextView(final Context context, final AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public JustifiedTextView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);

        if (attrs != null) {
            final TypedValue tv = new TypedValue();
            final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.JustifiedTextView, defStyle, 0);
            if (ta != null) {
                ta.getValue(R.styleable.JustifiedTextView_text, tv);

                if (tv.resourceId > 0) {
                    final String text = context.getString(tv.resourceId).replace("\n", "<br />");
                    loadDataWithBaseURL("file:///android_asset/",
                            "<html><head>" +
                                    "<link rel=\"stylesheet\" type=\"text/css\" href=\"justified_textview.css\" />" +
                                    "</head><body>" + text + "</body></html>",

                                    "text/html", "UTF8", null);
                    setTransparentBackground();
                }
            }
        }
    }

    public void setTransparentBackground() {
        try {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        } catch (final NoSuchMethodError e) {
        }

        setBackgroundColor(Color.TRANSPARENT);
        setBackgroundDrawable(null);
        setBackgroundResource(0);
    }
}

Wir müssen das Rendering auf Software einstellen, um einen transparenten Hintergrund für Android 3+ zu erhalten. Daher der Try-Catch für ältere Versionen von Android.

Hoffe das hilft!

PS: Bitte nicht, dass es nützlich sein könnte, dies zu Ihrer gesamten Aktivität auf Android 3+ hinzuzufügen, um das erwartete Verhalten zu erhalten:
android:hardwareAccelerated="false"

Benoit Duffez
quelle
Dies ist eine webView-basierte Lösung. Jeder hat bisher eine Textansicht gefunden, da die Textansicht leichter ist als die Webansicht und die Bildlaufansicht.
SuperUser
9

Sehr einfach Das können wir in der XML-Datei tun

<TextView 
android:justificationMode="inter_word"
/>
Machhindra Neupane
quelle
6

Ich schreibe meine eigene Klasse, um dieses Problem zu lösen. Hier ist es nur, dass Sie die statische Rechtfertigungsfunktion aufrufen müssen, die zwei Argumente akzeptiert

  1. Textansicht-Objekt
  2. Inhaltsbreite (Gesamtbreite Ihrer Textansicht)

//Hauptaktivität

package com.fawad.textjustification;
import android.app.Activity;
import android.database.Cursor;
import android.graphics.Point;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {
    static Point size;
    static float density;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Display display = getWindowManager().getDefaultDisplay();
        size=new Point();
        DisplayMetrics dm=new DisplayMetrics();
        display.getMetrics(dm);
        density=dm.density;
        display.getSize(size);


        TextView tv=(TextView)findViewById(R.id.textView1);
        Typeface typeface=Typeface.createFromAsset(this.getAssets(), "Roboto-Medium.ttf");
        tv.setTypeface(typeface);
        tv.setLineSpacing(0f, 1.2f);
        tv.setTextSize(10*MainActivity.density);

        //some random long text
         String myText=getResources().getString(R.string.my_text);

         tv.setText(myText);
        TextJustification.justify(tv,size.x);


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

// TextJustificationClass

package com.fawad.textjustification;

import java.util.ArrayList;

import android.graphics.Paint;
import android.text.TextUtils;
import android.widget.TextView;

public class TextJustification {

    public static void justify(TextView textView,float contentWidth) {
        String text=textView.getText().toString();
        Paint paint=textView.getPaint();

        ArrayList<String> lineList=lineBreak(text,paint,contentWidth);

        textView.setText(TextUtils.join(" ", lineList).replaceFirst("\\s", ""));
    }


    private static ArrayList<String> lineBreak(String text,Paint paint,float contentWidth){
        String [] wordArray=text.split("\\s"); 
        ArrayList<String> lineList = new ArrayList<String>();
        String myText="";

        for(String word:wordArray){
            if(paint.measureText(myText+" "+word)<=contentWidth)
                myText=myText+" "+word;
            else{
                int totalSpacesToInsert=(int)((contentWidth-paint.measureText(myText))/paint.measureText(" "));
                lineList.add(justifyLine(myText,totalSpacesToInsert));
                myText=word;
            }
        }
        lineList.add(myText);
        return lineList;
    }

    private static String justifyLine(String text,int totalSpacesToInsert){
        String[] wordArray=text.split("\\s");
        String toAppend=" ";

        while((totalSpacesToInsert)>=(wordArray.length-1)){
            toAppend=toAppend+" ";
            totalSpacesToInsert=totalSpacesToInsert-(wordArray.length-1);
        }
        int i=0;
        String justifiedText="";
        for(String word:wordArray){
            if(i<totalSpacesToInsert)
                justifiedText=justifiedText+word+" "+toAppend;

            else                
                justifiedText=justifiedText+word+toAppend;

            i++;
        }

        return justifiedText;
    }

}

// XML

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    tools:context=".MainActivity" 
    >



    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
         >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"

             >
            <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
        </LinearLayout>
    </ScrollView>

</RelativeLayout>
Fawad Badar
quelle
Bitte vervollständigen Sie dieses Beispiel mindestens, damit "\ n" oder System.getProperty ("line.separator") respektieren :)
ceph3us
5

FILL_HORIZONTAList äquivalent zu CENTER_HORIZONTAL. Sie können diesen Codeausschnitt im Quellcode von textview sehen:

case Gravity.CENTER_HORIZONTAL:
case Gravity.FILL_HORIZONTAL:
    return (mLayout.getLineWidth(0) - ((mRight - mLeft) -
            getCompoundPaddingLeft() - getCompoundPaddingRight())) /
            getHorizontalFadingEdgeLength();
Jiashie
quelle
4

Für dieses Problem gibt es eine benutzerdefinierte Ansicht. Diese benutzerdefinierte Textansicht unterstützt die Ansicht "Berechtigter Text".

Beute dies: JustifiedTextView

import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.view.View;

public class JustifiedTextView extends View {
        String text;
        ArrayList<Line> linesCollection = new ArrayList<Line>();
        TextPaint textPaint;
        Typeface font;
        int textColor;
        float textSize = 42f, lineHeight = 57f, wordSpacing = 15f, lineSpacing = 15f;
        float onBirim, w, h;
        float leftPadding, rightPadding;

        public JustifiedTextView(Context context, String text) {
                super(context);
                this.text = text;
                init();
        }

        private void init() {
                textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
                textColor = Color.BLACK;
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);

                if (font != null) {
                        font = Typeface.createFromAsset(getContext().getAssets(), "font/Trykker-Regular.ttf");
                        textPaint.setTypeface(font);
                }
                textPaint.setColor(textColor);

                int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
                w = resolveSizeAndState(minw, widthMeasureSpec, 1);
                h = MeasureSpec.getSize(widthMeasureSpec);

                onBirim = 0.009259259f * w;
                lineHeight = textSize + lineSpacing;
                leftPadding = 3 * onBirim + getPaddingLeft();
                rightPadding = 3 * onBirim + getPaddingRight();

                textPaint.setTextSize(textSize);

                wordSpacing = 15f;
                Line lineBuffer = new Line();
                this.linesCollection.clear();
                String[] lines = text.split("\n");
                for (String line : lines) {
                        String[] words = line.split(" ");
                        lineBuffer = new Line();
                        float lineWidth = leftPadding + rightPadding;
                        float totalWordWidth = 0;
                        for (String word : words) {
                                float ww = textPaint.measureText(word) + wordSpacing;
                                if (lineWidth + ww + (lineBuffer.getWords().size() * wordSpacing) > w) {// is
                                        lineBuffer.addWord(word);
                                        totalWordWidth += textPaint.measureText(word);
                                        lineBuffer.setSpacing((w - totalWordWidth - leftPadding - rightPadding) / (lineBuffer.getWords().size() - 1));
                                        this.linesCollection.add(lineBuffer);
                                        lineBuffer = new Line();
                                        totalWordWidth = 0;
                                        lineWidth = leftPadding + rightPadding;
                                } else {
                                        lineBuffer.setSpacing(wordSpacing);
                                        lineBuffer.addWord(word);
                                        totalWordWidth += textPaint.measureText(word);
                                        lineWidth += ww;
                                }
                        }
                        this.linesCollection.add(lineBuffer);
                }
                setMeasuredDimension((int) w, (int) ((this.linesCollection.size() + 1) * lineHeight + (10 * onBirim)));
        }

        @Override
        protected void onDraw(Canvas canvas) {
                super.onDraw(canvas);
                canvas.drawLine(0f, 10f, getMeasuredWidth(), 10f, textPaint);
                float x, y = lineHeight + onBirim;
                for (Line line : linesCollection) {
                        x = leftPadding;
                        for (String s : line.getWords()) {
                                canvas.drawText(s, x, y, textPaint);
                                x += textPaint.measureText(s) + line.spacing;
                        }
                        y += lineHeight;
                }
        }

        public String getText() {
                return text;
        }

        public void setText(String text) {
                this.text = text;
        }

        public Typeface getFont() {
                return font;
        }

        public void setFont(Typeface font) {
                this.font = font;
        }

        public float getLineHeight() {
                return lineHeight;
        }

        public void setLineHeight(float lineHeight) {
                this.lineHeight = lineHeight;
        }

        public float getLeftPadding() {
                return leftPadding;
        }

        public void setLeftPadding(float leftPadding) {
                this.leftPadding = leftPadding;
        }

        public float getRightPadding() {
                return rightPadding;
        }

        public void setRightPadding(float rightPadding) {
                this.rightPadding = rightPadding;
        }

        public void setWordSpacing(float wordSpacing) {
                this.wordSpacing = wordSpacing;
        }

        public float getWordSpacing() {
                return wordSpacing;
        }

        public float getLineSpacing() {
                return lineSpacing;
        }

        public void setLineSpacing(float lineSpacing) {
                this.lineSpacing = lineSpacing;
        }

        class Line {
                ArrayList<String> words = new ArrayList<String>();
                float spacing = 15f;

                public Line() {
                }

                public Line(ArrayList<String> words, float spacing) {
                        this.words = words;
                        this.spacing = spacing;
                }

                public void setSpacing(float spacing) {
                        this.spacing = spacing;
                }

                public float getSpacing() {
                        return spacing;
                }

                public void addWord(String s) {
                        words.add(s);
                }

                public ArrayList<String> getWords() {
                        return words;
                }
        }
}

Fügen Sie die obige Klasse zu Ihrem src-Ordner hinzu und verwenden Sie diesen Beispielcode, um sie Ihrem Layout hinzuzufügen:

JustifiedTextView jtv= new JustifiedTextView(getApplicationContext(), "Lorem ipsum dolor sit amet... ");
LinearLayout place = (LinearLayout) findViewById(R.id.book_profile_content);
place.addView(jtv);
Merter
quelle
4

siehe hier im Github

Importieren Sie einfach die beiden Dateien "TextJustifyUtils.java" und "TextViewEx.java" in Ihr Projekt.

public class TextJustifyUtils {
    // Please use run(...) instead
    public static void justify(TextView textView) {
        Paint paint = new Paint();

        String[] blocks;
        float spaceOffset = 0;
        float textWrapWidth = 0;

        int spacesToSpread;
        float wrappedEdgeSpace;
        String block;
        String[] lineAsWords;
        String wrappedLine;
        String smb = "";
        Object[] wrappedObj;

        // Pull widget properties
        paint.setColor(textView.getCurrentTextColor());
        paint.setTypeface(textView.getTypeface());
        paint.setTextSize(textView.getTextSize());

        textWrapWidth = textView.getWidth();
        spaceOffset = paint.measureText(" ");
        blocks = textView.getText().toString().split("((?<=\n)|(?=\n))");

        if (textWrapWidth < 20) {
            return;
        }

        for (int i = 0; i < blocks.length; i++) {
            block = blocks[i];

            if (block.length() == 0) {
                continue;
            } else if (block.equals("\n")) {
                smb += block;
                continue;
            }

            block = block.trim();

            if (block.length() == 0)
                continue;

            wrappedObj = TextJustifyUtils.createWrappedLine(block, paint,
                    spaceOffset, textWrapWidth);
            wrappedLine = ((String) wrappedObj[0]);
            wrappedEdgeSpace = (Float) wrappedObj[1];
            lineAsWords = wrappedLine.split(" ");
            spacesToSpread = (int) (wrappedEdgeSpace != Float.MIN_VALUE ? wrappedEdgeSpace
                    / spaceOffset
                    : 0);

            for (String word : lineAsWords) {
                smb += word + " ";

                if (--spacesToSpread > 0) {
                    smb += " ";
                }
            }

            smb = smb.trim();

            if (blocks[i].length() > 0) {
                blocks[i] = blocks[i].substring(wrappedLine.length());

                if (blocks[i].length() > 0) {
                    smb += "\n";
                }

                i--;
            }
        }

        textView.setGravity(Gravity.LEFT);
        textView.setText(smb);
    }

    protected static Object[] createWrappedLine(String block, Paint paint,
            float spaceOffset, float maxWidth) {
        float cacheWidth = maxWidth;
        float origMaxWidth = maxWidth;

        String line = "";

        for (String word : block.split("\\s")) {
            cacheWidth = paint.measureText(word);
            maxWidth -= cacheWidth;

            if (maxWidth <= 0) {
                return new Object[] { line, maxWidth + cacheWidth + spaceOffset };
            }

            line += word + " ";
            maxWidth -= spaceOffset;

        }

        if (paint.measureText(block) <= origMaxWidth) {
            return new Object[] { block, Float.MIN_VALUE };
        }

        return new Object[] { line, maxWidth };
    }

    final static String SYSTEM_NEWLINE = "\n";
    final static float COMPLEXITY = 5.12f; // Reducing this will increase
                                            // efficiency but will decrease
                                            // effectiveness
    final static Paint p = new Paint();

    public static void run(final TextView tv, float origWidth) {
        String s = tv.getText().toString();
        p.setTypeface(tv.getTypeface());
        String[] splits = s.split(SYSTEM_NEWLINE);
        float width = origWidth - 5;
        for (int x = 0; x < splits.length; x++)
            if (p.measureText(splits[x]) > width) {
                splits[x] = wrap(splits[x], width, p);
                String[] microSplits = splits[x].split(SYSTEM_NEWLINE);
                for (int y = 0; y < microSplits.length - 1; y++)
                    microSplits[y] = justify(removeLast(microSplits[y], " "),
                            width, p);
                StringBuilder smb_internal = new StringBuilder();
                for (int z = 0; z < microSplits.length; z++)
                    smb_internal.append(microSplits[z]
                            + ((z + 1 < microSplits.length) ? SYSTEM_NEWLINE
                                    : ""));
                splits[x] = smb_internal.toString();
            }
        final StringBuilder smb = new StringBuilder();
        for (String cleaned : splits)
            smb.append(cleaned + SYSTEM_NEWLINE);
        tv.setGravity(Gravity.LEFT);
        tv.setText(smb);
    }

    private static String wrap(String s, float width, Paint p) {
        String[] str = s.split("\\s"); // regex
        StringBuilder smb = new StringBuilder(); // save memory
        smb.append(SYSTEM_NEWLINE);
        for (int x = 0; x < str.length; x++) {
            float length = p.measureText(str[x]);
            String[] pieces = smb.toString().split(SYSTEM_NEWLINE);
            try {
                if (p.measureText(pieces[pieces.length - 1]) + length > width)
                    smb.append(SYSTEM_NEWLINE);
            } catch (Exception e) {
            }
            smb.append(str[x] + " ");
        }
        return smb.toString().replaceFirst(SYSTEM_NEWLINE, "");
    }

    private static String removeLast(String s, String g) {
        if (s.contains(g)) {
            int index = s.lastIndexOf(g);
            int indexEnd = index + g.length();
            if (index == 0)
                return s.substring(1);
            else if (index == s.length() - 1)
                return s.substring(0, index);
            else
                return s.substring(0, index) + s.substring(indexEnd);
        }
        return s;
    }

    private static String justifyOperation(String s, float width, Paint p) {
        float holder = (float) (COMPLEXITY * Math.random());
        while (s.contains(Float.toString(holder)))
            holder = (float) (COMPLEXITY * Math.random());
        String holder_string = Float.toString(holder);
        float lessThan = width;
        int timeOut = 100;
        int current = 0;
        while (p.measureText(s) < lessThan && current < timeOut) {
            s = s.replaceFirst(" ([^" + holder_string + "])", " "
                    + holder_string + "$1");
            lessThan = p.measureText(holder_string) + lessThan
                    - p.measureText(" ");
            current++;
        }
        String cleaned = s.replaceAll(holder_string, " ");
        return cleaned;
    }

    private static String justify(String s, float width, Paint p) {
        while (p.measureText(s) < width) {
            s = justifyOperation(s, width, p);
        }
        return s;
    }
}

und

public class TextViewEx extends TextView {
    private Paint paint = new Paint();

    private String[] blocks;
    private float spaceOffset = 0;
    private float horizontalOffset = 0;
    private float verticalOffset = 0;
    private float horizontalFontOffset = 0;
    private float dirtyRegionWidth = 0;
    private boolean wrapEnabled = false;
    int left, top, right, bottom = 0;
    private Align _align = Align.LEFT;
    private float strecthOffset;
    private float wrappedEdgeSpace;
    private String block;
    private String wrappedLine;
    private String[] lineAsWords;
    private Object[] wrappedObj;

    private Bitmap cache = null;
    private boolean cacheEnabled = false;

    public TextViewEx(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // set a minimum of left and right padding so that the texts are not too
        // close to the side screen
        // this.setPadding(10, 0, 10, 0);
    }

    public TextViewEx(Context context, AttributeSet attrs) {
        super(context, attrs);
        // this.setPadding(10, 0, 10, 0);
    }

    public TextViewEx(Context context) {
        super(context);
        // this.setPadding(10, 0, 10, 0);
    }

    @Override
    public void setPadding(int left, int top, int right, int bottom) {
        // TODO Auto-generated method stub
        super.setPadding(left + 10, top, right + 10, bottom);
    }

    @Override
    public void setDrawingCacheEnabled(boolean cacheEnabled) {
        this.cacheEnabled = cacheEnabled;
    }

    public void setText(String st, boolean wrap) {
        wrapEnabled = wrap;
        super.setText(st);
    }

    public void setTextAlign(Align align) {
        _align = align;
    }

    @SuppressLint("NewApi")
    @Override
    protected void onDraw(Canvas canvas) {
        // If wrap is disabled then,
        // request original onDraw
        if (!wrapEnabled) {
            super.onDraw(canvas);
            return;
        }

        // Active canas needs to be set
        // based on cacheEnabled
        Canvas activeCanvas = null;

        // Set the active canvas based on
        // whether cache is enabled
        if (cacheEnabled) {

            if (cache != null) {
                // Draw to the OS provided canvas
                // if the cache is not empty
                canvas.drawBitmap(cache, 0, 0, paint);
                return;
            } else {
                // Create a bitmap and set the activeCanvas
                // to the one derived from the bitmap
                cache = Bitmap.createBitmap(getWidth(), getHeight(),
                        Config.ARGB_4444);
                activeCanvas = new Canvas(cache);
            }
        } else {
            // Active canvas is the OS
            // provided canvas
            activeCanvas = canvas;
        }

        // Pull widget properties
        paint.setColor(getCurrentTextColor());
        paint.setTypeface(getTypeface());
        paint.setTextSize(getTextSize());
        paint.setTextAlign(_align);
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);

        // minus out the paddings pixel
        dirtyRegionWidth = getWidth() - getPaddingLeft() - getPaddingRight();
        int maxLines = Integer.MAX_VALUE;
        int currentapiVersion = android.os.Build.VERSION.SDK_INT;
        if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            maxLines = getMaxLines();
        }
        int lines = 1;
        blocks = getText().toString().split("((?<=\n)|(?=\n))");
        verticalOffset = horizontalFontOffset = getLineHeight() - 0.5f; // Temp
                                                                        // fix
        spaceOffset = paint.measureText(" ");

        for (int i = 0; i < blocks.length && lines <= maxLines; i++) {
            block = blocks[i];
            horizontalOffset = 0;

            if (block.length() == 0) {
                continue;
            } else if (block.equals("\n")) {
                verticalOffset += horizontalFontOffset;
                continue;
            }

            block = block.trim();

            if (block.length() == 0) {
                continue;
            }

            wrappedObj = TextJustifyUtils.createWrappedLine(block, paint,
                    spaceOffset, dirtyRegionWidth);

            wrappedLine = ((String) wrappedObj[0]);
            wrappedEdgeSpace = (Float) wrappedObj[1];
            lineAsWords = wrappedLine.split(" ");
            strecthOffset = wrappedEdgeSpace != Float.MIN_VALUE ? wrappedEdgeSpace
                    / (lineAsWords.length - 1)
                    : 0;

            for (int j = 0; j < lineAsWords.length; j++) {
                String word = lineAsWords[j];
                if (lines == maxLines && j == lineAsWords.length - 1) {
                    activeCanvas.drawText("...", horizontalOffset,
                            verticalOffset, paint);

                } else if (j == 0) {
                    // if it is the first word of the line, text will be drawn
                    // starting from right edge of textview
                    if (_align == Align.RIGHT) {
                        activeCanvas.drawText(word, getWidth()
                                - (getPaddingRight()), verticalOffset, paint);
                        // add in the paddings to the horizontalOffset
                        horizontalOffset += getWidth() - (getPaddingRight());
                    } else {
                        activeCanvas.drawText(word, getPaddingLeft(),
                                verticalOffset, paint);
                        horizontalOffset += getPaddingLeft();
                    }

                } else {
                    activeCanvas.drawText(word, horizontalOffset,
                            verticalOffset, paint);
                }
                if (_align == Align.RIGHT)
                    horizontalOffset -= paint.measureText(word) + spaceOffset
                            + strecthOffset;
                else
                    horizontalOffset += paint.measureText(word) + spaceOffset
                            + strecthOffset;
            }

            lines++;

            if (blocks[i].length() > 0) {
                blocks[i] = blocks[i].substring(wrappedLine.length());
                verticalOffset += blocks[i].length() > 0 ? horizontalFontOffset
                        : 0;
                i--;
            }
        }

        if (cacheEnabled) {
            // Draw the cache onto the OS provided
            // canvas.
            canvas.drawBitmap(cache, 0, 0, paint);
        }
    }
}

Wenn Sie nun eine normale Textansicht verwenden, wie:

<TextView
                android:id="@+id/original"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/lorum_ipsum" />

Einfach benutzen

<yourpackagename.TextViewEx
                android:id="@+id/changed"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/lorum_ipsum" />

Definieren Sie eine Variable und setzen Sie die Rechtfertigung auf wahr.

TextViewEx changed = (TextViewEx) findViewById(R.id.changed);
changed.setText(getResources().getString(R.string.lorum_ipsum),true);
Mr_Moradi
quelle
Fettdruck funktioniert nicht, bitte helfen Sie, wenn Sie eine Lösung dafür haben.
Praveenb
4

Android Text Justify For TextView XML

Einfach Android Text-Rechtfertigung in XML verwenden. Sie können einfach in Textansicht Widget implementieren.

 <TextView
    android:justificationMode="inter_word"
/>

Standard ist android:justificationMode="none"

Samad Talukder
quelle
2

Ich denke, es gibt zwei Möglichkeiten:

  • Verwenden Sie etwas wie Pango, das sich über das NDK darauf spezialisiert hat, und rendern Sie Text in eine OpenGL oder eine andere Oberfläche.

  • Verwenden Sie Paint.measureText () und Freunde, um die Länge der Wörter zu ermitteln und sie manuell auf einer Leinwand in einer benutzerdefinierten Ansicht anzuordnen .

Matthew Willis
quelle
2

Wenn Sie auf Android links Text ausrichten und die Hintergrundfarbe nicht abschneiden möchten, versuchen Sie dies. Es hat bei mir funktioniert und konsistente Ergebnisse auf Android, ff, dh & chrome erzielt. Sie müssen jedoch den dazwischen liegenden Platz für den Text messen bei der Berechnung der Polsterung.

<td style="font-family:Calibri,Arial;
    font-size:15px;
    font-weight:800;
    background-color:#f5d5fd;
    color:black;
    border-style:solid;
    border-width:1px;
    border-color:#bd07eb;
    padding-left:10px;
    padding-right:1000px;
    padding-top:3px;
    padding-bottom:3px;
>

Der Hack ist der padding-right:1000px;, der den Text ganz nach links drückt.

Jeder Versuch, nach links zu gehen oder Code in CSS oder HTML zu rechtfertigen, führt zu einem Hintergrund, der nur halb so breit ist.

Robin Glas
quelle
1

Android unterstützt noch keine vollständige Begründung. Wir können Webview verwenden und HTML rechtfertigen, anstatt Textview zu verwenden. Es funktioniert so gut. Wenn ihr nicht klar seid, zögern Sie nicht mich zu fragen :)

kypiseth
quelle
Das kann man machen. Aber können wir Hintergrund setzen von WebView transparent. Ich habe ein Hintergrundbild.
Mr.India
Ich glaube nicht, dass dies in Bezug auf die Erinnerung möglich ist.
SuperUser
1

TextView-Inhaltsbegründung: Die einfachen Leute verwenden einfach android: justificationMode = "inter_word" in Ihrem TextView-Tag.

 <TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="92dp"
    android:text="@string/contents"
    android:layout_margin="20dp"
    android:justificationMode="inter_word"
     />
Ashraf Gardizy
quelle
-4

Versuchen Sie es mit < RelativeLayout >(stellen Sie sicher, dass fill_parent vorhanden ist), und fügen Sie dann einfach android:layout_alignParentLeft="true"und hinzu

android:layout_alignParentRight="true" zu den Elementen, die Sie außen LINKS & RECHTS möchten.

Schuld, gerechtfertigt!

esharp
quelle
gutes
esharp
3
Ist immer noch nicht das, wonach er sucht. Siehe Begründung bei Wikipedia: en.wikipedia.org/wiki/Justification_(typesetting)
Kevin Coppock
Es ist keine Rechtfertigung
Arash Hatami
-5

Du musst einstellen

android:layout_height="wrap_content"

und

android:layout_centerInParent="true"
Lukas
quelle
11
Dies zentriert den Text, der nicht vollständig gerechtfertigt ist
Janusz
-12

Dies rechtfertigt Ihren Text aber nicht wirklich

android:gravity="center_horizontal"

ist die beste Wahl, die Sie haben.

Wolfen
quelle
9
Nein, das zentriert den Text. Es rechtfertigt es nicht. Zitat von Wikipedia : "In gerechtfertigtem Text werden die Zwischenräume zwischen Wörtern und in geringerem Maße zwischen Glyphen oder Buchstaben (Kerning) gestreckt oder manchmal komprimiert, damit der Text sowohl am linken als auch am rechten Rand ausgerichtet wird."
CommonsWare
Der Text ist nicht durch Ihren Code gerechtfertigt, sondern zentriert den Text horizontal
Matteo