Android TextView Metni Yasla


396

Bir metni nasıl alırsınız? TextViewA'nın metnini Yaslanmış olarak (sol ve sağ taraftaki hizalı metinle)?

Burada olası bir çözüm buldum , ancak çalışmıyor (dikey merkezi center_vertical vb. Olarak değiştirseniz bile).


@Jimbo cevap kesinlikle doğru çalışıyor benim durumumda üzerinde inputText ve textview sol giriş ve ekrana sağdan arap dili için ancak giriş metin için ben de yerçekimi = "right" eklemek zorunda
Shareef'ten

Yanıtlar:


239

Android'in tam gerekçesi desteklediğine inanmıyorum.

GÜNCELLEME 2018-01-01 : Android 8.0+ ile yaslama modlarınıTextView destekler .


5
Daha fazla analiz üzerine, android verebilir: gravity = "fill_horizontal" bir atış. Bu "Gerekirse nesnenin yatay boyutunu büyütün, böylece kabını tamamen doldurur" olarak tanımlanır, ancak metni nasıl "büyüttüklerini" bilmiyorum.
CommonsWare

8
android: gravity = "fill_horizontal" da çalışmadı. Görünüşe göre android sonuçta haklılığı desteklemiyor, oh iyi :)

6
Hayır, mülkü yerçekimi gibi ayarlayamazsınız. Ancak yine de, metin görünümü yerine web görünümü alarak metninizin gerekçesini ayarlayabilirsiniz. Seal.io/2010/12/only-way-how-to-align-text-in-block-in.html adresine başvurabilirsiniz . (Çaldığı stackoverflow.com/questions/5976627/... )
jcaruso

2
@CommonsWare Şimdi metni doğrulamak için uygun bir yol var mı?
John R

1
Dostum, bunu başarmak için ağır bir web görünümü ile yaşıyorum ve inan bana, kullanıcı arayüzüm henüz API'ye eklenecek bazı yeni şeyler için ağlıyor, çünkü bir liste görünümünde sohbet gibi bileşenler için çok yavaş.
nobalG

156

@CommonsWare yanıtı doğrudur. Android 8.0+, "Tam Gerekçelendirme" yi (veya bazen belirsiz bir şekilde belirtildiği gibi "Gerekçelendirme") desteklemez.

Android ayrıca "Sola / Sağa Metin Hizala" özelliğini de destekler. Gerekçe ile ilgili wikipedia makalesine bakınAyrım için . Birçok kişi, tam gerekçe ve sol / sağ metin hizalamasını kapsayan 'gerekçe' kavramını düşünür; bu da sol / sağ metin hizalaması yapmak istediklerinde aramaları gereken şeydir. Bu cevap, sol / sağ metin hizalamasının nasıl gerçekleştirileceğini açıklar.

Sola / Sağa Metin Hizalaması elde etmek mümkündür (tam olarak gerekçelendirmenin aksine, sorunun sorduğu gibi). Bunu göstermek için örnek olarak 2 sütunlu bir form kullanacağım (sol sütundaki etiketler ve sağ sütundaki metin alanları). Bu örnekte, sol sütundaki etiketlerdeki metin sağa hizalanacak, böylece sağ sütundaki metin alanlarıyla aynı hizada görünecektir.

XML mizanpajında, tüm TextView'lerin içine aşağıdaki özniteliği ekleyerek TextView öğelerinin kendilerinin (sol sütun) sağa hizalanmasını sağlayabilirsiniz:

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

Ancak, metin birden çok satıra sarılırsa, metin yine de TextView içinde hizalı olarak sola yaslanır. Aşağıdaki özniteliğin eklenmesi, gerçek metni TextView içinde sağa hizalı (solda düzensiz) hizalar:

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

Bu nedenle gravity özniteliği, TextView içindeki metnin nasıl hizalanacağını belirtir layout_gravity , TextView öğesinin kendisinin nasıl hizalanacağını / düzenleneceğini belirtir.


12
Doğru anlarsam ve bunu test etmenin sonuçları verilirse, tüm bunlar metni sola veya sağa hizalamaktır. Bu metni haklı çıkarmaz, değil mi?
Paul Lammertsma

14
Mükemmel. Sadece eklemek için, eğer merkez haklılığını istiyorsanız, bunu yapabilirsiniz android:layout_gravity="center_horizontal|center" android:gravity="center".
Luis A. Florit

kesinlikle benim durum için çalışma inputText ve textview sol girdi ve ekran sağdan arap dili için
Shareef'ten

1
Bu sadece hizalama, gerekçe değil. Bu Wikipedia bağlantısını dikkatlice okuyun. Farklı gerekçelendirme türleri arasındaki fark yalnızca paragrafın son satırını etkiler. Yalnızca bir satırı olan paragraflar için sol / sağ / merkez gerekçesi yoktur.
Karu

o zaman neden olmasa bile burada yanıtlıyoruzjustify
user924 15:18

136

Android'deki metni haklı çıkarmak için WebView kullandım

    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");

ve 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>

Henüz kanıtlamak için resim yükleyemiyorum ama "benim için çalışıyor".


3
Burada güzel bir çözüm. FWIW ekstra html çoğu gerekmez. Metin hizalamalı gövde etiketi yeterlidir.
gnac

5
Bu iyi çalışıyor. Eğer takip ederek arka planı saydam hale unutmayın view.loadData()ile view.setBackgroundColor("#00000000").
Paul Lammertsma

Ancak, özel bir yazı tipi / yazı tipi yüklemek için başarılı olamadım. Ben denedim bu ve bu olmadan herhangi bir şans, öneri.
Paul Lammertsma

2
Bu iş parçacıklarında bahsettiğim gibi, bir çözüm buldum: HTML dosyası oluşturup öğelere yerleştirirseniz, view.loadUrl()çalışır durumdayken yükleme view.loadData()yapmaz. İkincisinin neden olmadığına dair hiçbir fikrim yok.
Paul Lammertsma

1
@PaulLammertsma, setBackgroundColor (0x00000000), şeffaf arka planı ayarlamak için doğru biçim olacaktır.
richey

100

GÜNCELLENMİŞ

Bunun için basit bir sınıf yarattık. Şu anda aradığınızı elde etmek için iki yöntem vardır. Her ikisi de WEBVIEW YOK ve SPANNABLLARI DESTEKLEMEKTİR .

KÜTÜPHANE : https://github.com/bluejamesbond/TextJustify-Android

DESTEKLER : Android 2.0 - 5.X

KURMAK

// Please visit Github for latest setup instructions.

EKRAN GÖRÜNTÜSÜ

Comparison.png


Gerçekten yardımcı olur, ancak bunu kullanarak, TextViews'ım orijinal formatını korumaz, refeer: kenar boşlukları, metin stili ve sanırım Plese metin boyutunda da çalışmaya devam etmiyor, gerçekten harika bir yardım olmalı
Leonardo Sapuy

O sınıfları kuramıyorum. bir tanesinin paket adı yoktu, diğeri sarı hata veriyor. Aslında güvenemiyorum.
mehmet

Güzel bir lib, ama hala bu kütüphaneyi kullanarak Text'e nasıl bir format ekleyeceğimi bilmiyorum.
Semanticer

4
Bu büyük paylaşılan kütüphane için teşekkürler, ancak farsça veya arapça metni destekleyemez. Yönü ayarladığımda, kelimem başlangıçtan son yerine sondan başlayarak çiziyor. Demek istediğim şu: Benim Sözüm: "سلام" ve bunun gibi çizmek: "مالس". (Farsça anlamıyorsanız, bu örneğe bakın: "1234" -> "4321" olsun)
Naruto Uzumaki

1
ScrollView dayalı ... Güzel bir çözüm ancak textview ile mümkün kılan herhangi bir cevap bulamıyorum. :(
superUser

88

TextViewin Android Okendisi tam bir gerekçe (yeni tipografik hizalama) sunar.

Bunu yapmanız yeterlidir:

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);
}

varsayılan değer JUSTIFICATION_MODE_NONE.


3
Umarım destek kütüphanesine geri taşınır o zaman O :)
Stefan Haustein

2
pls buraya kütüphane ekleyin !!
Kunal Dharaiya

4
XML kullanarak nasıl gerekçelendirilir?
Vikash Parajuli

14
Xml'de android: justificationMode = "inter_word" kullanabilirsiniz.
Christian D

5
Android için API 26 gerekir: justificationMode.
Bink

42

Github'da Android için JustifiedTextView projesini kullanabilirsiniz . bu, sizin için doğrulanmış metni simüle eden özel bir görünümdür. Android 2.0+ ve sağdan sola dilleri destekler. resim açıklamasını buraya girin


spannable string'i desteklemiyor
MSepehr

kendi metnimizi nasıl ekleyebiliriz?
Karan

Lütfen github üzerindeki örneğe bakınız.
Saeed Zarinfam

merhaba Saeed, yardımınız için tnx, spannable metin görüşlerini desteklemek için herhangi bir yolu var mı ?!
Hamid Reza

@SaeedZarinfam "Android için JustifiedTextView" kullanmaya çalıştım ama ir.noghteh.JustifiedTextView xml etiketinde hata var u bu soru bana yardımcı olmak için plz olurdu stackoverflow.com/questions/37911376/…
Jumong

30

Bunu yapmak için yerel metin görünümünde bir widget tabanı yazıyorum.

github


Ben bunu tavsiye, çoğunlukla onun android görüş sdk orijinal textview dayalı, ki benim kişisel görüşüme göre birçok kişi bu ortak konu ile ilgili webview tekniği daha hafif bir yol daha hafif. Örneğin, listview nesnelerini kullanarak bellek açısından akıllı olması gereken bir uygulama oluşturuyorsanız, bunun gibi bir şey kullanmayı düşünebilirsiniz. Ï allready denemek ve beklendiği gibi çalışıyor. Eğer insanlar böyle bir tanesini daha iyi biliyorlarsa, lütfen deneyimlerinizi benimle paylaşabilirsiniz.
superUser

İyi iş btw. Aradığım şey.
superUser

5
farsça gibi RTL dillerini desteklemiyor
delikte yangın

1
@Frank Cheng Çok Yararlı Kütüphane. Paragrafın sonunda çok yer var. Nasıl düzeltebilirim?
iSrinivasan27

1
benim için çalıştı, ancak metin görünümünün son satırı kesildi. Ben textview için 5 dolgu tutmak zorunda kaldı.
TharakaNirmana

23

Bu sorunu çözmenin bir yolunu buldum, ancak bu çok zarafet olmayabilir, ancak etkisi kötü değil.

Prensibi, her satırın boşluklarını sabit genişlikli ImageSpan ile değiştirmektir (renk şeffaftır).

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);
            }
        }
    });
}

Kodu GitHub'a koydum: https://github.com/twiceyuan/TextJustification

Genel bakış:

genel bakış


1
Değil XML önizleme çalışan ama :) gerçek cihazla çalışmak büyük
pgreze

15

XML Düzeni: TextView yerine WebView bildirme

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

Java kodu: metin verilerini WebView olarak ayarla

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");

Bu sorununuzu çözebilir. Tamamen benim için çalıştı.


9

İşte böyle yaptım, bence en zarif yol. Bu çözümle, mizanpajlarınızda yapmanız gereken tek şey şunlardır:

  • ek bir xmlnsbeyan ekle
  • değiştir TextView yeni ad android den ler kaynak metin ad
  • senin yerine TextViewsx.y.z.JustifiedTextView

İşte kod. Telefonlarımda mükemmel çalışıyor (Galaxy Nexus Android 4.0.2, Galaxy Teos Android 2.1). Elbette, paket adımı sizinkilerle değiştirmekten çekinmeyin.

/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);
    }
}

Android 3+ üzerinde şeffaf arka plan elde etmek için oluşturmayı yazılıma ayarlamamız gerekiyor. Bu nedenle Android'in eski sürümleri için try-catch.

Bu yardımcı olur umarım!

Not: beklenen davranışı elde etmek için bunu Android 3+ üzerindeki tüm etkinliğinize eklemenin yararlı olabileceğini lütfen unutmayın:
android:hardwareAccelerated="false"


Bu webView tabanlı bir çözümdür. Metin görüntülemenin web görünümü ve kaydırma görünümünden daha açık olduğu düşünüldüğünde henüz metin görünümü tabanlı olan herhangi biri.
superUser



6

Bu sorunu çözmek için kendi sınıfımı yazıyorum, işte sadece iki argüman alan statik yaslama işlevini çağırmanız gerekiyor

  1. Metin Görüntüleme nesnesi
  2. İçerik Genişliği (Metin görünümünüzün toplam genişliği)

//Ana aktivite

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>

en azından "\ n" veya System.getProperty ("line.separator") saygı duymak için bu örneği tamamlayın :)
ceph3us

5

FILL_HORIZONTALeşittir CENTER_HORIZONTAL. Bu kod snippet'ini textview'in kaynak kodunda görebilirsiniz:

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

4

Bu sorun için bir CustomView vardır, bu özel metin görünümü Yaslanmış Metin Görünümü'nü destekler.

Bunu yağmala : 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;
                }
        }
}

Yukarıdaki sınıfı src klasörünüze ekleyin ve düzeninize eklemek için şu örnek kodu kullanın:

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

4

buraya github'da bakın

Projenizde "TextJustifyUtils.java" ve "TextViewEx.java" adlı iki dosyayı içe aktarmanız yeterlidir.

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;
    }
}

ve

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);
        }
    }
}

Şimdi normal textView kullanıyorsanız:

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

Basitçe kullanın

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

Bir değişken tanımlayın ve iki yana yaslama değerini doğru olarak ayarlayın,

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

kalın metin çalışmıyor, bunun için herhangi bir düzeltmeniz varsa lütfen yardım edin?
praveenb

4

Android Metin TextView XML İçin Yasla

Sadece XML kullanarak android metin-haklı. Metin görünümü widget'ında basitçe uygulayabilirsiniz.

 <TextView
    android:justificationMode="inter_word"
/>

Varsayılan değer android:justificationMode="none"


2

Bence iki seçenek var:

  • Bu konuda NDK aracılığıyla uzmanlaşmış Pango gibi bir şey kullanın ve metni bir OpenGL veya başka bir yüzeye dönüştürün.

  • Kullanım Paint.measureText () ve arkadaşlar kelimelerin uzunlukları almak ve özel bir görünümünde bir tuval bunları manuel ortaya koymak.


2

Android'de, metni yaslamak ve arka plan renginin kısaltılmaması için, bunu deneyin, benim için çalıştı, android, ff, yani & chrome'da tutarlı sonuçlar üretiyor, ancak metin için kalan boşluğu ölçmeniz gerekiyor dolgu hesaplarken.

<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;
>

Kesmek padding-right:1000px; aşırı sola metin iten.

Css veya html'de sola veya kodu yaslamak için yapılan herhangi bir girişim, yalnızca yarım genişlikte bir arka planla sonuçlanır.



1

Android henüz tam gerekçesi desteklemiyor. Webview'i kullanabilir ve textview yerine HTML'yi yaslayabiliriz. Çok iyi çalışıyor. Eğer net değilseniz, bana sormaya çekinmeyin :)


Bu yapılabilir. Ama arka planını ayarlayabilir miyiz WebView transparent. Bir arka plan resmim var.
Hindistan

Bunun hafıza açısından akıllı olabileceğini sanmıyorum.
superUser


1

TextView İçerik Gerekçesi: Kolay adamları sadece TextView etiketinizde android: justificationMode = "inter_word" kullanır.

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


-5

Ayarlamak zorundasın

android:layout_height="wrap_content"

ve

android:layout_centerInParent="true"

11
Bu tam bir gerekçe olmayan metni merkezler
Janusz

-12

Bu gerçekten metninizi haklı çıkarmıyor,

android:gravity="center_horizontal"

sahip olduğunuz en iyi seçimdir.


9
Hayır, metni ortalar. Bunu haklı çıkarmaz. Wikipedia'dan alıntı : "Yaslanmış metinde, kelimeler arasındaki ve daha az ölçüde glifler veya harfler (karakter aralığı) arasındaki boşluklar, metnin hem sol hem de sağ kenar boşluklarıyla hizalanması için uzatılır veya bazen sıkıştırılır."
CommonsWare

metin kodunuza göre değil, metni yatay olarak konumlandırır
Matteo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.