Android: la última línea de textview cortó

Tengo un LinearLayout horizontal que contiene un TextView seguido de un Spinner lado. Este LinearLayout se infla dinámicamente varias veces en un LinearLayout vertical LinearLayout contenido dentro de un RelativeLayout .

El problema es que desde que Theme.light de Theme.light a Theme.holo.light , la última línea de TextView se reduce a la mitad. Esto sucede cuando el texto dynamic es largo y abarca más de una fila.

enter image description here

Pude solucionar esto agregando relleno de fondo al LinearLayout horizontal que contiene TextView y Spinner .

Esto no se siente como una solución, sino más como un truco. ¿Puede alguien darme algún consejo sobre cómo corregir esto correctamente?

También he leído algunas otras preguntas, pero ninguna parece ayudar.

Diseño lineal horizontal:

      

Diseño relativo donde el diseño anterior está inflado dinámicamente en Layout lineal con id ll2_7:

            

EDITAR: Aquí está el xml de diseño completo para arriba:

     

Después de probar un millón de cosas diferentes, creo que tengo la respuesta.

LayoutGravity un LayoutGravity al elemento TextView:

 android:layout_gravity="fill" 

Parece resolver todos los problemas de recorte que tuve. Espero que esto ayude a alguien con el mismo problema.

Me he encontrado con el mismo problema de corte que se muestra en la captura de pantalla. Es causado por la alineación de la línea base en LinearLayout horizontal. TextView y Spinner tienen líneas de base diferentes debido a la diferencia de tamaño de fuente. Para solucionar el problema, es necesario desactivar la alineación de línea base para el diseño mediante la configuración:

 android:baselineAligned="false" 

o en el código:

 layout.setBaselineAligned(false); 

Tuve el mismo problema, y ​​encontré que simplemente agregando

 android:includeFontPadding="false" 

la línea final de texto ya no tenía recortados sus descensores.

Agregué un espacio ficticio después del texto agregando

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

Intenté todas las demás soluciones. Pero esta fue la única solución que funcionó para mí

Cuando esto ocurre, debe asegurarse de que TextView no crezca más de lo que es contenedor:

Si un TextView se establece en wrap_content y su contenedor (o un contenedor antecesor) no deja espacio para que TextView crezca, puede ocluirse.

Si ese no es el caso, también es posible que onMeasure() de TextView veces no mida correctamente las colas de las letras, los caracteres no latinos o los efectos del texto en cursiva. Puede corregir esto configurando un estilo global para su TextView modo que se TextView sin necesidad de cambiar toda la base de códigos:

Asegúrese de que su aplicación / actividades use un tema personalizado como ese:

   

La respuesta de @Rynadt fue realmente útil para llegar a la etapa anterior. Establecer la gravedad del texto dentro de la vista asegura que en algunos dispositivos la oclusión nunca se lleva a cabo (el texto se ajusta correctamente dentro de la vista); en otros, una mano amiga con relleno de un valor sp se asegura de que las colas y demás se tengan en cuenta con un valor específico de TextSize.

Encontré una solución diferente al extender TextView y agregar una Clase personalizada como esta:

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

prueba con la eliminación de android: paddingBottom = “20dp”

de

   

Mi solución fue cercana a la aceptada, pero tuve que cambiarla a

  android:layout_gravity="fill_vertical" 

en lugar. De lo contrario, las otras filas se habrían estirado también con saltos de línea adicionales en lugares aleatorios. Por ejemplo, la fila más grande tenía 4 líneas, por lo que se cambió otra fila de

this is a testphrase

a

 thi s is a testph rase 

Puede usar un oyente de diseño global para un TextView en cualquier tipo de 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); } } }); 

Puedes leer más sobre esto aquí

Coloque la vista de texto problemática dentro de un framelayout. Creo que la vista de texto no se calculó correctamente debido a la vista de hermanos, Spinner.

 < ?xml version="1.0" encoding="utf-8"?>       

Si tiene este problema y su TextView está dentro de RelativeLayout , intente cambiar el RelativeLayout por un LinearLayout .

Eso solucionó el problema para mí

Creo que hay muy poco que puede hacer para que esto funcione alterando los diseños. Como he descubierto, algunos métodos funcionan solo en algunos casos. Creo que depende de la jerarquía de diseño completa y no es una solución única para todos. También noté que sucede especialmente cuando tienes una fuente diferente que deseas establecer en TextView.

Un método de disparo seguro que he experimentado y probado es que puede establecer los atributos de fuente en código una vez que la vista está inflada. Supongo que tiene una fuente en la carpeta assets / fonts que quiere.

Por ejemplo, en un Fragmento:

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

Y en una actividad:

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

Tengo el mismo problema, y ​​es muy molesto.

Solo sucede con el texto en árabe.

Si convierte la etiqueta en varias líneas y agrega una \n al final de la cadena, la arreglaría, pero el problema es que habría una gran brecha entre esta etiqueta y el objeto debajo de ella, debido al hecho de que este campo ahora tiene una nueva línea vacía debajo de él.

Se puede hacer un control personalizado para evitarlo. Pero en general, este es un error molesto.

getViewTreeObserver().addOnGlobalLayoutListener no funciona en una vista de reciclador. Si está utilizando un reciclador, use View.addOnLayoutChangeListener :

Descubrí que la elipsis que definí para textView en xml no siempre se reflejaba, por lo que la programé programáticamente antes de reasignar la propiedad del texto. Esto funcionó para mí.

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

La mejor solución para esto es agregar una vista ficticia de la altura deseada (es decir, esto agregará relleno) en la parte inferior de su vista.

    

Como en mi caso, agregué una fila de tabla más en la parte inferior de la vista. Espero que esto pueda ayudar a alguien.

Sé que es muy tarde, pero esto funciona como un encanto para mí. agregue este código a su textview

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

¡Finalmente lo arreglé!

Intento agregar String a TextView en el Servicio y luego llamar a scrollTo (), ¡se cortará la última línea!

El scrollTo () debería llamarse en “Runnable”, como:

 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 creo porque en el momento de llamar a scrollTo () en servicio, la actualización de TextView no está lista.