Cómo obtener el número de líneas de TextView?

Quiero obtener el número de líneas de una vista de texto

textView.setText("Test line 1 Test line 2 Test line 3 Test line 4 Test line 5.............") 

textView.getLineCount(); Siempre devuelve cero

Entonces también he intentado:

 ViewTreeObserver vto = this.textView.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { ViewTreeObserver obs = textView.getViewTreeObserver(); obs.removeGlobalOnLayoutListener(this); System.out.println(": " + textView.getLineCount()); } }); 

Devuelve la salida exacta.

Pero esto sólo funciona para un diseño estático.

Cuando estoy inflando el diseño dinámicamente esto no funciona más.

¿Cómo puedo encontrar el número de línea en un TextView?

Pude obtener getLineCount() para no devolver 0 usando una post , como esto:

 textview.setText(“Some text”); textview.post(new Runnable() { @Override public void run() { int lineCount = textview.getLineCount(); // Use lineCount here } }); 

Como se menciona en este post ,

getLineCount() le dará el número correcto de líneas sólo después de un pase de diseño.

Significa que necesita procesar el TextView primero antes de invocar el método getLineCount() .

ViewTreeObserver no es tan confiable especialmente cuando se utilizan diseños dinámicos como ListView.

Supongamos: 1. Usted hará un trabajo dependiendo de las líneas de TextView. 2. El trabajo no es muy urgente y se puede hacer más tarde.

Aquí está mi solución:

 public class LayoutedTextView extends TextView { public LayoutedTextView(Context context) { super(context); } public LayoutedTextView(Context context, AttributeSet attrs) { super(context, attrs); } public LayoutedTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public interface OnLayoutListener { void onLayouted(TextView view); } private OnLayoutListener mOnLayoutListener; public void setOnLayoutListener(OnLayoutListener listener) { mOnLayoutListener = listener; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (mOnLayoutListener != null) { mOnLayoutListener.onLayouted(this); } } } 

Uso:

  LayoutedTextView tv = new LayoutedTextView(context); tv.setOnLayoutListener(new OnLayoutListener() { @Override public void onLayouted(TextView view) { int lineCount = view.getLineCount(); // do your work } }); 

Creo que el quid de esta pregunta es que la gente quiere ser capaz de averiguar el tamaño de un TextView de antemano para que puedan cambiar de tamaño dinámicamente para encajar perfectamente con el texto. Un uso típico podría ser crear burbujas de charla (al menos eso era lo que estaba trabajando).

He intentado varias soluciones, incluyendo el uso de getTextBounds () y measureText () como se discute aquí . Desafortunadamente, ambos métodos son poco inexactos y no tienen forma de tener en cuenta los saltos de línea y el espacio de líneas no utilizado. Por lo tanto, renuncié a ese enfoque.

Eso deja getLineCount (), cuyo problema es que tienes que "renderizar" el texto antes de getLineCount () te dará el número de líneas, lo que lo convierte en una situación de gallina y huevo. Leí varias soluciones involucrando a los oyentes y los diseños, pero simplemente no podía creer que no había algo más simple.

Después de violar durante dos días, finalmente encontré lo que estaba buscando (al menos funciona para mí). Todo se reduce a lo que significa "renderizar" el texto. No significa que el texto tiene que aparecer en la pantalla, sólo que tiene que estar preparado para su visualización interna. Esto ocurre siempre que una llamada se hace directamente a invalidate () o indirectamente como cuando se hace un setText () en su TextView, que llama invalidate () para usted ya que la vista ha cambiado de aspecto.

De todas maneras, aquí está el código de la clave (supongamos que ya conoce la lineWidth y lineHeight de la burbuja de la conversación de una sola línea basada en la fuente):

 TextView talkBubble; // No peeking while we set the bubble up. talkBubble.setVisibility( View.INVISIBLE ); // I use FrameLayouts so my talk bubbles can overlap // lineHeight is just a filler at this point talkBubble.setLayoutParams( new FrameLayout.LayoutParams( lineWidth, lineHeight ) ); // setText() calls invalidate(), which makes getLineCount() do the right thing. talkBubble.setText( "This is the string we want to dynamically deal with." ); int lineCount = getLineCount(); // Now we set the real size of the talkBubble. talkBubble.setLayoutParams( new FrameLayout.LayoutParams( lineWidth, lineCount * lineHeight ) ); talkBubble.setVisibility( View.VISIBLE ); 

De todos modos, eso es todo. El redibujo siguiente dará una burbuja a medida para su texto.

Nota: En el programa actual, utilizo una burbuja separada para determinar las líneas de texto de modo que pueda cambiar el tamaño de mi burbuja real dinámicamente tanto en términos de longitud como de ancho. Esto me permite reducir mis burbujas de izquierda a derecha para declaraciones cortas, etc.

¡Disfrutar!

Basado en la idea de @secnelis , incluso hay una manera más limpia si se apunta a la API 11 o superior.

En lugar de extender un TextView , puede utilizar la funcionalidad View.OnLayoutChangeListener si View.OnLayoutChangeListener

En ListAdapter.getView() , por ejemplo

 if (h.mTitle.getLineCount() == 0 && h.mTitle.getText().length() != 0) { h.mTitle.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(final View v, final int left, final int top, final int right, final int bottom, final int oldLeft, final int oldTop, final int oldRight, final int oldBottom) { h.mTitle.removeOnLayoutChangeListener(this); final int count = h.mTitle.getLineCount(); // do stuff } }); } else { final int count = h.mTitle.getLineCount(); // do stuff } 

¿Estás haciendo esto onCreate ? Las Vistas no se han establecido aún, así que getLineCount() es 0 por un tiempo. Si lo hace más tarde en el Window LifeCycle, obtendrá su línea de contar. Tendrás dificultades para hacerlo onCreate , pero onWindowFocusChanged con hasFocus=true usualmente tiene las Vistas medidas por ahora.

La sugerencia textView.post() también es buena

  holder.tv_prayerDesc.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { try { final int lineCount = holder.tv_prayerDesc.getLayout().getLineCount(); Log.e("linecount",lineCount+""); if(lineCount<=5) { holder.show.setVisibility(View.GONE); } }catch (Exception e) { e.printStackTrace(); } return true; } }); 
  • TextView escribe texto verticalmente cuando configura sus layoutparams a fill_parent
  • Cómo hacer que un TextView parezca un encabezado PreferenciaCategoría de un ajuste
  • Establecer el estilo TextView (en negrita o en cursiva)
  • Android TextView debe desplazarse verticalmente automáticamente
  • Utilice la imagen GIF en ImageSpan con un EditText
  • ImageSpan.ALIGN_BASELINE cuando TextView tiene lineSpacing
  • Cómo obtener el ancho de textView en android
  • Android conjunto grado símbolo de Textview
  • .length () vs .getText (). Length () vs .getText (). ToString (). Length ()
  • Android - Destacar una palabra en un TextView?
  • ¿Hay una manera de centrar perfectamente el texto?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.