it-swarm.com.de

Android TextView Text ausrichten

Wie kann der Text eines TextView gerechtfertigt werden (mit bündigem Text auf der linken und rechten Seite)?

Ich habe eine mögliche Lösung gefunden hier , aber es funktioniert nicht (auch wenn Sie die vertikale Mitte in die vertikale Mitte ändern usw.).

369
user130076

Ich glaube nicht, dass Android die volle Rechtfertigung unterstützt.

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

219
CommonsWare

Die Antwort von @CommonsWare ist richtig. Android unterstützt nicht "Vollständige Rechtfertigung" (oder einfach "Rechtfertigung", da manchmal mehrdeutig darauf verwiesen wird).

Android unterstützt jedoch "Flush Left/Right Text Alignment". Siehe den Wikipedia-Artikel auf Begründung für die Unterscheidung. Viele Menschen denken, dass das Konzept der 'Ausrichtung' sowohl die vollständige Ausrichtung als auch die Ausrichtung von Text nach links und rechts umfasst. Dies ist das, wonach sie suchen, wenn sie Text nach links und rechts ausrichten möchten. In dieser Antwort wird erläutert, wie Sie die Textausrichtung links/rechts erreichen.

Es ist möglich, Flush Left/Right Text Alignment zu erreichen (im Gegensatz zu Full Justification, wie in der Frage gefragt wird). Zur Veranschaulichung verwende ich ein einfaches zweispaltiges Formular (Beschriftungen in der linken Spalte und Textfelder in der rechten Spalte) als Beispiel. In diesem Beispiel wird der Text in den Beschriftungen in der linken Spalte rechtsbündig ausgerichtet, sodass er bündig mit den Textfeldern in der rechten Spalte angezeigt wird.

Im XML-Layout können Sie die TextView-Elemente selbst (die 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 umgebrochen wird, wird der Text in der Textansicht immer noch linksbündig ausgerichtet. Durch das Hinzufügen des folgenden Attributs wird der tatsächliche Text in der Textansicht rechtsbündig ausgerichtet (linksbündig):

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

Das Attribut Schwerkraft gibt an, wie der Text in der Textansicht ausgerichtet werden soll layout_gravity Legt fest, wie das TextView-Element selbst ausgerichtet/angeordnet wird.

158
plainjimbo

Zum Ausrichten von Text in Android 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 es zu beweisen, aber "es funktioniert für mich".

132
Konrad Nowicki

AKTUALISIERT

Wir haben dafür eine einfache Klasse erstellt. Derzeit gibt es zwei Methoden, um das zu erreichen, wonach Sie suchen. Beide benötigen NO WEBVIEW und SUPPORTS SPANNABLES .

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

UNTERSTÜTZT: Android 2.0 bis 5.X

SETUP

// Please visit Github for latest setup instructions.

SCREENSHOT

Comparison.png

98
Mathew Kurian

TextView in Android O bietet die vollständige Ausrichtung (neue typografische Ausrichtung) an sich.

Sie müssen nur das tun,

textView.setJustificationMode(JUSTIFICATION_MODE_INTER_Word);

standard ist JUSTIFICATION_MODE_NONE.

60
Jaydipsinh Zala

Sie können JustifiedTextView für Android project in github verwenden. Hierbei handelt es sich um eine benutzerdefinierte Ansicht, mit der Sie den richtigen Text simulieren können. Es unterstützt Android 2.0+ und von rechts nach links Sprachen. enter image description here

39
Saeed Zarinfam

Ich schreibe ein Widget auf Basis der nativen Textansicht, um dies zu tun.

Github

28
Frank Cheng

Ich habe einen Weg gefunden, 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 das 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:

Overview

21
twiceYuan

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 die 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.

16
user2599233

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

  • fügen Sie eine zusätzliche xmlns -Deklaration hinzu
  • ändern Sie den Quelltext-Namespace von TextView von Android in Ihren neuen Namespace
  • ersetzen Sie Ihre TextViews durch x.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 Android-Versionen.

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"

9
Benoit Duffez

Während noch kein vollständiger Blocksatz vorhanden ist, können Sie jetzt mit Android:breakStrategy="balanced" ab API 23 die Zeilenlängen ausgleichen

http://developer.Android.com/reference/Android/widget/TextView.html#attr_Android:breakStrategy

9
kassim

Ich schreibe meine eigene Klasse, um dieses Problem zu lösen. Hier müssen Sie nur die statische Ausrichtungsfunktion aufrufen, 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>
6
Fawad Badar

FILL_HORIZONTAL entspricht 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();
5
jiashie

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

Beute dabei: 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 Ihr Layout zu erweitern:

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

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

<TextView 
Android:justificationMode="inter_Word"
/>
3

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" />

Definiere eine Variable und setze justify auf true,

TextViewEx changed = (TextViewEx) findViewById(R.id.changed);
changed.setText(getResources().getString(R.string.lorum_ipsum),true);
2
Mr_Moradi

Versuchen Sie diese Lösung im folgenden Link, erstellen Sie einfach diese Klasse im Projektordner und verwenden Sie sie. es funktioniert gut für mich :)

Text in einer Android App mit einem WebView ausrichten, aber eine TextView-ähnliche Oberfläche präsentieren?

2
Yoganand.N

Wenn Sie unter Android Text linksbündig ausrichten und die Hintergrundfarbe nicht abschneiden möchten, versuchen Sie dies. Es hat bei mir funktioniert und unter Android, ff, dh & chrome, zu konsistenten Ergebnissen geführt. Sie müssen jedoch den verfügbaren Platz abmessen Dazwischen bleibt der Text 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, Code in CSS oder HTML nach links zu verschieben oder zu rechtfertigen, führt zu einem Hintergrund, der nur halb so breit ist.

2
Robin Glas

Android unterstützt noch nicht die vollständige Rechtfertigung. Wir können Webview verwenden und HTML anstelle von Textview ausrichten. Es funktioniert so gut. Wenn ihr nicht klar seid, könnt ihr mich gerne fragen :)

2
kypiseth

Ich denke, es gibt zwei Möglichkeiten:

  • Verwenden Sie etwas wie Pango, das sich über das NDK darauf spezialisiert hat, und rendern Sie Text auf einer OpenGL-Oberfläche oder einer anderen Oberfläche.

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

2
Matthew Willis

Für die HTML-Formatierung müssen Sie das Webkit nicht aufrufen, sondern können Html.fromHtml(text) verwenden, um die Aufgabe zu erledigen.

Quelle: http://developer.Android.com/guide/topics/resources/string-resource.html

1
SaturnTheIcy