Android: ultima riga della visualizzazione testo troncata


113

Ho un orizzontale LinearLayoutcontenente un TextViewseguito da un Spinneraccanto ad esso. Questo LinearLayoutviene gonfiato dinamicamente più volte in una verticale fissa LinearLayoutcontenuta in un file RelativeLayout.

Il problema è che da quando sono passato da Theme.lighta Theme.holo.light, l'ultima riga TextViewviene tagliata a metà. Ciò accade quando il testo dinamico è lungo e si estende su più di una riga.

inserisci qui la descrizione dell'immagine

Sono stato in grado di risolvere questo problema aggiungendo un'imbottitura inferiore all'orizzontale LinearLayoutcontenente TextViewe Spinner.

Non sembra una soluzione, ma più un trucco. Qualcuno può darmi qualche consiglio su come risolvere correttamente questo problema?

Ho letto anche altre domande, ma nessuna sembra essere d'aiuto.

Layout lineare orizzontale:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dp"
        android:text="TextView"/>

    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

Layout relativo in cui il layout sopra viene gonfiato dinamicamente al layout lineare con ID ll2_7:

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

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/relLayoutButtonNext"
        android:layout_below="@id/textView1" >

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="20dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="10dp" >

            <TextView
                android:id="@+id/textView10"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingRight="30dp"
                android:text="2.7" />

            <TextView
                android:id="@+id/textView11"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:layout_toRightOf="@id/textView10"
                android:text="@string/question2_7" />


            <LinearLayout
                android:id="@+id/ll2_7"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView11"
                android:layout_below="@+id/textView11"
                android:orientation="vertical" android:layout_marginBottom="20dp">
            </LinearLayout>

        </RelativeLayout>

    </ScrollView>

</RelativeLayout>

EDIT: Ecco il layout completo xml per sopra:

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

    <TextView
        android:id="@+id/textView1"
        style="@style/question_section_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="@string/question2_header" />

    <RelativeLayout
        android:id="@+id/relLayoutButtonNext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@color/bottomBar"
        android:paddingBottom="3dp"
        android:paddingLeft="50dp"
        android:paddingRight="50dp"
        android:paddingTop="3dp" >

        <Button
            android:id="@+id/buttonNext"
            android:layout_width="180dp"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:onClick="nextStep"
            android:text="Next Section"
            android:textSize="20sp" />

        <Button
            android:id="@+id/buttonPrevious"
            android:layout_width="180dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:onClick="previousStep"
            android:text="Previous Section"
            android:textSize="20sp" />
    </RelativeLayout>


    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/relLayoutButtonNext"
        android:layout_below="@id/textView1" >



        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="20dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="10dp" >

            <TextView
                android:id="@+id/textView10"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingRight="30dp"
                android:text="2.7" />

            <TextView
                android:id="@+id/textView11"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:layout_toRightOf="@id/textView10"
                android:text="@string/question2_7" />


            <LinearLayout
                android:id="@+id/ll2_7"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView11"
                android:layout_below="@+id/textView11"
                android:orientation="vertical" android:layout_marginBottom="20dp">

            </LinearLayout>

            <TextView
                android:id="@+id/textView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView10"
                android:layout_below="@+id/ll2_7"
                android:text="2.8" />

            <TextView
                android:id="@+id/textView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/ll2_7"
                android:layout_toRightOf="@+id/textView10"
                android:text="@string/question2_8" android:layout_marginBottom="10dp"/>


            <LinearLayout
                android:id="@+id/ll2_8"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView3"
                android:layout_below="@+id/textView3"
                android:layout_marginBottom="20dp"
                android:orientation="vertical" >

            </LinearLayout>

            <TextView
                android:id="@+id/textView4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView2"
                android:layout_below="@+id/ll2_8"
                android:text="2.9" />

            <TextView
                android:id="@+id/textView5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/ll2_8"
                android:layout_toRightOf="@+id/textView10"
                android:text="@string/question2_9" android:layout_marginBottom="10dp"/>


            <LinearLayout
                android:id="@+id/ll2_9"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/textView5"
                android:layout_toRightOf="@+id/textView10"
                android:orientation="vertical" android:layout_marginBottom="20dp">

            </LinearLayout>

            <TextView
                android:id="@+id/textView6"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView4"
                android:layout_below="@+id/ll2_9"
                android:text="2.10" />

            <TextView
                android:id="@+id/textView7"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/ll2_9"
                android:layout_toRightOf="@+id/textView10"
                android:text="@string/question2_10" android:layout_marginBottom="10dp"/>


            <LinearLayout
                android:id="@+id/ll2_10"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/textView7"
                android:layout_marginBottom="20dp"
                android:layout_toRightOf="@+id/textView10"
                android:orientation="vertical" >

            </LinearLayout>

            <TextView
                android:id="@+id/textView8"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView6"
                android:layout_below="@+id/ll2_10"
                android:text="2.11" />

            <TextView
                android:id="@+id/textView9"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/ll2_10"
                android:layout_toRightOf="@+id/textView10"
                android:text="@string/quesiton2_11" android:layout_marginBottom="10dp"/>


            <LinearLayout
                android:id="@+id/ll2_11"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView9"
                android:layout_below="@+id/textView9"
                android:orientation="vertical" android:layout_marginBottom="20dp">

            </LinearLayout>

            <TextView
                android:id="@+id/textView12"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignLeft="@+id/textView8"
                android:layout_below="@+id/ll2_11"
                android:text="2.11.1" />

            <TextView
                android:id="@+id/textView13"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/ll2_11"
                android:layout_toRightOf="@+id/textView10"
                android:text="@string/question2_11_1" android:layout_marginBottom="10dp"/>


            <LinearLayout
                android:id="@+id/ll2_11_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/textView13"
                android:layout_toRightOf="@+id/textView10"
                android:orientation="vertical" android:layout_marginBottom="20dp">

            </LinearLayout>

        </RelativeLayout>

    </ScrollView>

</RelativeLayout>

prova a rimuovere Android: paddingBottom = "20dp"
Dheeresh Singh

2
Prova a riempire la visualizzazione del testo e anche i margini del layout lineare possono dare una bella mano
Aashish Bhatnagar

LinearLayout è davvero problematico se usato in orizzontale. Utilizzare invece ConstraintLayout. Vedere. stackoverflow.com/a/48677954/630668
Dharmendra

Risposte:


55

Ho riscontrato lo stesso problema di interruzione mostrato nello screenshot. È causato dall'allineamento della linea di base in orizzontale LinearLayout. TextViewe Spinnerhanno linee di base diverse a causa della differenza di dimensione del carattere. Per risolvere il problema è necessario disabilitare l'allineamento della linea di base per il layout impostando:

android:baselineAligned="false"

o nel codice:

layout.setBaselineAligned(false);

2
Vorrei poter votare 100 volte! Ho perso moltissimo tempo negli ultimi giorni su questo problema e la tua risposta è stata la mia soluzione! Non mi rendevo conto di cosa stesse succedendo da così tanto tempo perché è così difficile eseguire il debug della gerarchia di visualizzazione su Android. Grazie mille!!!
mbm29414

Questa era la soluzione al mio problema, oltre alla risposta di Rynardt. Grazie!
James Dobson

1
Questa è la risposta corretta e indica il motivo per cui si è verificato l'errore. Grazie.
Hoang Nguyen Huu

Questo è un suggerimento enorme per situazioni come questa. Non è affatto male. Grazie!
sunlover 3

260

Dopo aver provato un milione di cose diverse, penso di avere la risposta.

Ho applicato LayoutGravitya all'elemento TextView:

android:layout_gravity="fill"

Sembra risolvere tutti i problemi di clipping che ho avuto. Spero che questo aiuti qualcuno con lo stesso problema.


12
perfetto, tnx, +1; nota che molti valori di layout_gravity aiutano, ad es. center_vertical
Grzegorz Dev

2
Se questo non funziona, dovrebbe funzionare l'aggiunta di un valore di riempimento di "1sp". Creo uno stile che si estende @android:style/Widget.TextViewe aggiungo le seguenti righe:<item name="android:gravity">fill</item> <item name="android:padding">1sp</item>
Graeme

perché questo problema si verifica solo con il testo arabo ?!
Menna-Allah Sami,

12
Questa è solo una soluzione alternativa. La soluzione corretta è aggiungere android:baselineAligned="false"al tuoLinearLayout
tomrozb

1
Anche se sembra funzionare, la soluzione corretta è quella del commento di tomrozb sopra, o la risposta di Jusid
Eduard B.

28

Ho avuto lo stesso problema e l'ho scoperto semplicemente aggiungendo

android:includeFontPadding="false"

l'ultima riga di testo non aveva più i suoi discendenti tagliati.


1
Con i caratteri personalizzati, questa potrebbe essere la soluzione perfetta. Questa è l'unica soluzione che ha funzionato per me quando utilizzo Droid Sans Japanese.
Computingfreak

11

Ho aggiunto un po 'di spazio fittizio dopo il testo aggiungendo

textView.setText(firstString+"\n");

Ho provato tutte le altre soluzioni, ma questa era l'unica soluzione che funzionava per me


questo è quello che chiami "chepi"
Zulqurnain Jutt

6

Metti la visualizzazione di testo problematica all'interno di un framelayout. Penso che la visualizzazione del testo non sia calcolata correttamente a causa della visualizzazione di pari livello, Spinner.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <FrameLayout
        android:layout_width="150dp"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/textView1"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:text="TextView"/>
    </FrameLayout>
    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

1
Ho avuto lo CheckBoxstesso LinearLayout. Questo ha risolto il problema.
Chintan Shah

Ha funzionato a
meraviglia

5

Quando ciò si verifica, dovresti assicurarti che TextViewnon stia crescendo più grande del suo contenitore -

Se a TextViewè impostato su wrap_contente il suo contenitore (o un contenitore antenato) non lascia spazio per la TextViewcrescita, può essere occluso.

Se questo non è il caso, è anche possibile la onMeasure()del TextViewa volte non misura correttamente le code di lettere, caratteri non latini o gli effetti di testo che sono in corsivo. Puoi correggerlo impostando uno stile globale per il tuo in TextViewmodo che venga raccolto senza bisogno di cambiare l'intera base di codice:

Assicurati che la tua applicazione / attività utilizzi un tema personalizzato in questo modo:

<style name="Custom" parent="@android:style/Theme.Light">   
    <item name="android:textViewStyle">@style/Custom.Widget.TextView</item>
</style>

<style name="Custom.Widget.TextView" parent="@android:style/Widget.TextView"> 
    <item name="android:gravity">fill</item>
    <item name="android:padding">1sp</item>
</style>

La risposta di @Rynadt è stata davvero utile per arrivare alla fase precedente. L'impostazione della gravità del testo all'interno della vista garantisce su alcuni dispositivi che l'occlusione non si verifichi mai (il testo è adattato correttamente all'interno della vista), su altri una mano con imbottitura di un valore sp, assicura che le code e altri siano presi in considerazione con un valore specifico TextSize.


5

La mia soluzione era vicina a quella accettata, ma ho dovuto cambiarla in

   android:layout_gravity="fill_vertical"

anziché. Altrimenti anche le altre righe sarebbero state allungate con l'aggiunta di interruzioni di riga in punti casuali. Ad esempio, la riga più grande aveva 4 righe, quindi un'altra riga è stata modificata da

this is a testphrase

per

thi
s is
a testph
rase

1
Per me va bene. Grazie! +1
Ahmed

5

Ho trovato una soluzione diversa estendendo TextView e aggiungendo una classe personalizzata come questa:

 public class AdaptingTextView extends TextView {

    public AdaptingTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

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

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        // set fitting lines to prevent cut text
        int fittingLines = h / this.getLineHeight();
        if (fittingLines > 0) {
            this.setLines(fittingLines);
        }
    }

}

Funziona alla grande, ma fai attenzione se hai layout_margin specificato nella textview in quanto può alterare il numero di linee di adattamento in modo che sia più corto di quanto dovrebbe essere! Sono passato a utilizzare il padding invece dei margini e il problema è stato risolto
MobileMon

1
Funziona perfettamente. Di gran lunga la migliore soluzione che ho trovato.
Moonbloom

1
Questa è la risposta corretta, grazie! Per renderlo un po 'più carino e aggiungere "..." alla fine del testo prima che venga troncato, aggiungi this.setEllipsize(TextUtils.TruncateAt.END);l'istruzione if sopra e rimuovi android:ellipsize="end"dall'XML che per qualche motivo lo rompe.
NeilS

4

prova a rimuovere android: paddingBottom = "20dp"

a partire dal

 <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="20dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:paddingTop="10dp" >

1
Il padding in realtà non è correlato in quanto vi sono elementi aggiuntivi contenuti all'interno di questo layout relativo con il padding. Li ho rimossi per facilitare la lettura di questo post. Vedi modifica in questione.
Rynardt

4

getViewTreeObserver().addOnGlobalLayoutListenernon funziona in una visualizzazione riciclatore. Se stai usando un riciclatore, usa View.addOnLayoutChangeListener:

Ho scoperto che l'ellipsize che ho definito textViewin xml non si rifletteva sempre, quindi l'ho impostato a livello di codice prima di riassegnare la proprietà text. Questo ha funzionato per me.

textView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
    @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom,
                                   int oldLeft, int oldTop, int oldRight, int oldBottom) {
            textView.removeOnLayoutChangeListener(this);
            float lineHeight = textView.getLineHeight();
            int maxLines = (int) (textView.getHeight() / lineHeight);
            if (textView.getLineCount() != maxLines) {
                textView.setLines(maxLines);
                textView.setEllipsize(TextUtils.TruncateAt.END);
                // Re-assign text to ensure ellipsize is performed correctly.
                textView.setText(model.getText());
            }
        }
    });

3

Se hai questo problema e il tuo TextViewè all'interno di un RelativeLayout, prova a cambiare il RelativeLayoutper aLinearLayout .

Questo ha risolto il problema per me


Questa è l'unica soluzione che funziona per me (comportamento strano)! Thx
mrroboaat

1
Come puoi semplicemente "passare" da RelativeLayout a LinearLayout? Se devi layout relativamente è quasi impossibile implementarlo con LinearLayout.
L'incredibile gennaio

3

È possibile utilizzare un listener di layout globale per un TextView in qualsiasi tipo di ViewGroup.

    final TextView dSTextView = (TextView)findViewById(R.id.annoyingTextView);
dSTextView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {
        dSTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this);

        float lineHeight = dSTextView.getLineHeight();
        int maxLines = (int) (dSTextView.getHeight() / lineHeight);

        if (dSTextView.getLineCount() != maxLines) {
            dSTextView.setLines(maxLines);
        }

    }
});

Puoi leggere di più al riguardo qui


1

Penso che ci sia molto poco che puoi fare per farlo funzionare alterando i layout. Come ho scoperto che alcuni metodi funzionano solo in alcuni casi. Penso che dipenda dall'intera gerarchia del layout e non sia una soluzione valida per tutti. Ho anche notato che succede soprattutto quando hai un carattere diverso che vuoi impostare su TextView.

Un metodo sicuro che ho sperimentato e testato è che puoi impostare gli attributi del carattere nel codice dopo che la vista è stata gonfiata. Presumo che tu abbia un font nella cartella assets / fonts che desideri.

Ad esempio in un frammento:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState)
{
    View view = inflater.inflate(R.layout.fragment_view, container, false);
    TextView tv = (TextView)view.findViewById(R.id.text_view);
    tv.setText("Insert text that needs to be displayed");
    AssetManager assetManager = getContext().getAssets();
    Typeface typeFace = Typeface.createFromAsset(assetManager, "Fonts/OpenSans-Light.ttf");
    tv.setTypeface(typeFace , 0); // 0 is normal font
    tv.setPadding(10,  0, 10, 0); // This is not mandatory
}

E in un'attività:

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(Resource.Layout.main_activity);
    TextView tv = (TextView)this.findViewById(R.id.text_view);
    tv.setText("Insert text that needs to be displayed");
    AssetManager assetManager = getContext().getAssets();
    Typeface typeFace = Typeface.createFromAsset(assetManager, "Fonts/OpenSans-Light.ttf");
    tv.setTypeface(typeFace , 0); // 0 is normal font
    tv.setPadding(10,  0, 10, 0); // This is not mandatory
}

1

Ho lo stesso problema ed è molto fastidioso.

Succede solo con il testo arabo.

Se crei l'etichetta su più righe e aggiungi un file \n alla fine della stringa, il problema verrà risolto, ma il problema è che ci sarebbe un grande divario tra questa etichetta e l'oggetto sottostante, a causa del fatto che questo campo ora ha una nuova riga vuota sotto di essa.

È possibile eseguire un controllo personalizzato per aggirare il problema. Ma nel complesso, questo è un bug fastidioso.


Se hai una NUOVA domanda, chiedila facendo clic sul pulsante Fai domanda . Se hai una reputazione sufficiente, puoi votare a favore della domanda. In alternativa, "contrassegnalo come preferito" e riceverai una notifica di eventuali nuove risposte.
Martijn Pieters

0

La soluzione migliore per questo è aggiungere una vista fittizia dell'altezza desiderata (cioè questo aggiungerà il riempimento stesso) nella parte inferiore della vista.

<TableRow
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:layout_marginLeft="5dp"
 android:layout_marginRight="5dp" >
     <View 
       android:layout_width="match_parent" 
       android:layout_height="30dp"/>
</TableRow>

Come nel mio caso, ho aggiunto un'altra riga della tabella nella parte inferiore della visualizzazione. Spero che questo possa aiutare qualcuno.


0

So che è così tardi, ma questo è un lavoro affascinante per me. aggiungi questo codice al tuotextview

android:ellipsize="marquee"
android:layout_weight="1"

0

Aggiungi padding alla parte inferiore della visualizzazione del testo:

android:paddingBottom="24dp"

-1

Finalmente l'ho risolto!

Provo ad aggiungere String a TextView in Service e quindi chiamo scrollTo (), l'ultima riga viene troncata!

Lo scrollTo () dovrebbe essere chiamato in "Runnable", come:

private ScrollView mScrollView;
public void scrollToBottom()
{
    mScrollView = (ScrollView) findViewById(R.id.debug_textview_scrollview);
    mScrollView.post(new Runnable()
    {
        public void run()
        {
            mScrollView.fullScroll(View.FOCUS_DOWN);
        }
    });
}

Lo penso perché nel momento della chiamata scrollTo () in servizio, l'aggiornamento di TextView non è pronto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.