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
- Cómo asignar el tamaño de texto en el valor de sp usando código java
- ¿Por qué mi interfaz de usuario de Android actúa como falsa cuando intento seleccionar texto?
- Eliminar el fondo de una vista de texto
- ¿Hay una manera fácil de agregar un borde a la parte superior e inferior de una vista de Android?
- Cómo eliminar ellipsized propiedad de TextView de código?
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?
- TextView que está vinculado y seleccionable?
- Paginación en Android TextView
- Android: TextView dañado usando .setShader ()
- Cómo hacer TextView se ve exactamente como EditText?
- Cómo cambiar el espaciado de letras en una vista de texto?
- Aumentar el tamaño de la fuente en función del tamaño del dispositivo
- ¿Por qué TextView.setTypeface () aumenta exageradamente mi altura TextView cuando uso la fuente Roboto-Italic.ttf?
- ¿Cómo agrego un símbolo de viñeta en 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; } });
- El editor de diseño de Android Studio no puede mostrar vistas personalizadas
- Responsabilidades de la actividad / fragmento de Android para la carga de datos