¿Hay una manera de hacer ellipsize = "marquee" siempre desplazarse?

Quiero utilizar el efecto de la marquesina en un TextView, pero el texto está siendo desplazado solamente cuando el TextView consigue el foco. Eso es un problema, porque en mi caso, no puede.

Estoy usando:

android:ellipsize="marquee" android:marqueeRepeatLimit="marquee_forever" 

¿Hay alguna forma de que el TextView siempre desplace su texto? He visto esto que se hace en la aplicación de Android Market, donde el nombre de la aplicación se desplazará en la barra de título, incluso si no recibe el foco, pero no pude encontrar esto que se menciona en los documentos de la API.

He estado haciendo frente al problema y la solución más corta he venido para arriba con crear una nueva clase derivada de TextView. La clase debe anular tres métodos onFocusChanged , onWindowFocusChanged y isFocused para hacer que el TextView esté enfocado.

 @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { if(focused) super.onFocusChanged(focused, direction, previouslyFocusedRect); } @Override public void onWindowFocusChanged(boolean focused) { if(focused) super.onWindowFocusChanged(focused); } @Override public boolean isFocused() { return true; } 

Finalmente me encontré con este problema hoy y así disparó hierarchyviewer en la aplicación Android Market.

Mirando el título en la pantalla de detalle de una aplicación, usan un TextView antiguo TextView . El examen de sus propiedades demostró que no estaba enfocado, no podía enfocarse y era generalmente muy ordinario, excepto por el hecho de que estaba marcado como seleccionado .

Una línea de código más tarde y tuve que trabajar 🙂

 textView.setSelected(true); 

Esto tiene sentido, dado lo que el Javadoc dice :

Se puede seleccionar una vista o no. Tenga en cuenta que la selección no es lo mismo que el enfoque. Las vistas se seleccionan típicamente en el contexto de un AdapterView como ListView o GridView.

Es decir, cuando se desplaza por encima de un elemento en una vista de lista (como en la aplicación Market), sólo entonces el texto ahora seleccionado comenzará a desplazarse. Y puesto que este TextView particular no es TextView o clickable, nunca perderá su estado de la selección.

Por desgracia, por lo que sé, no hay manera de predefinir el estado seleccionado de la disposición XML.
Pero el uno-trazador de líneas arriba trabaja muy bien para mí.

Sólo tiene que poner estos parámetros en su TextView. Funciona 🙂

  android:singleLine="true" android:ellipsize="marquee" android:marqueeRepeatLimit ="marquee_forever" android:scrollHorizontally="true" android:focusable="true" android:focusableInTouchMode="true" 

No sé si todavía necesitas la respuesta, pero encontré una manera fácil de hacer esto.

Configure su animación de la siguiente manera:

 Animation mAnimation = new TranslateAnimation(START_POS_X, END_POS_X, START_POS_Y, END_POS_Y); mAnimation.setDuration(TICKER_DURATION); mAnimation.setRepeatMode(Animation.RESTART); mAnimation.setRepeatCount(Animation.INFINITE); 

START_POS_X , END_POS_X , START_POS_Y y END_POS_Y son valores float , mientras que TICKER_DURATION es un int declarado con mis otras constantes.

A continuación, puede aplicar esta animación a su TextView:

 TextView tickerText = (TextView) findViewById(R.id.ticker); tickerText.setAnimation(mAnimation); 

Y eso es. 🙂

Mi animación comienza en el lado derecho fuera de pantalla (300f) y termina en el lado izquierdo fuera de pantalla (-300f), con una duración de 15s (15000).

TranslateAnimation funciona "tirando" la Vista en una dirección por una cantidad especificada. Puede establecer dónde comenzar este "tracción" y dónde finalizar.

 TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta); 

FromXDelta establece el desplazamiento de la posición inicial del movimiento en el eje X.

 fromXDelta = 0 //no offset. fromXDelta = 300 //the movement starts at 300px to the right. fromXDelta = -300 //the movement starts at 300px to the left 

ToXDelta define la posición final de desplazamiento del movimiento en el eje X.

 toXDelta = 0 //no offset. toXDelta = 300 //the movement ends at 300px to the right. toXDelta = -300 //the movement ends at 300px to the left. 

Si el ancho del texto es mayor que el módulo de la diferencia entre fromXDelta y toXDelta, el texto no será capaz de moverse totalmente y compeltely dentro de la pantalla.


Ejemplo

Supongamos que nuestro tamaño de pantalla es 320×240 pxs. Tenemos un TextView con un texto que tiene un ancho de 700px y queremos crear una animación que "tire" el texto para que podamos ver el final de la frase.

  (screen) +---------------------------+ |<----------320px---------->| | | |+---------------------------<<<< X px >>>> movement<-----|| some TextView with text that goes out... |+--------------------------- | unconstrained size 700px | | | | | +---------------------------+ +---------------------------+ | | | | <<<< X px >>>>---------------------------+| movement<----- some TextView with text that goes out... || ---------------------------+| | | | | | | +---------------------------+ 

Primero fijamos fromXDelta = 0 para que el movimiento no tenga un offset inicial. Ahora tenemos que calcular el valor toXDelta. Para lograr el efecto deseado necesitamos "tirar" el texto del mismo px exacto que se extiende fuera de la pantalla. (En el esquema se representa por <<<< X px >>>>) Dado que nuestro texto tiene 700 ancho, y el área visible es 320px (ancho de pantalla) que establecemos:

 tXDelta = 700 - 320 = 380 

¿Y cómo calculamos el ancho de la pantalla y el ancho del texto?


Código

Tomando el fragmento Zarah como punto de partida:

  /** * @param view The Textview or any other view we wish to apply the movement * @param margin A margin to take into the calculation (since the view * might have any siblings in the same "row") * **/ public static Animation scrollingText(View view, float margin){ Context context = view.getContext(); //gets the context of the view // measures the unconstrained size of the view // before it is drawn in the layout view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); // takes the unconstrained wisth of the view float width = view.getMeasuredWidth(); // gets the screen width float screenWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth(); // perfrms the calculation float toXDelta = width - (screenWidth - margin); // sets toXDelta to 0 if the text width is smaller that the screen size if (toXDelta < 0) {toXDelta = 0; } else { toXDelta = 0 - toXDelta;} // Animation parameters Animation mAnimation = new TranslateAnimation(0, toXDelta, 0, 0); mAnimation.setDuration(15000); mAnimation.setRepeatMode(Animation.RESTART); mAnimation.setRepeatCount(Animation.INFINITE); return mAnimation; } 

Puede haber formas más sencillas de realizar esto, pero esto funciona para cada vista que se pueda pensar y es reutilizable. Es especialmente útil si desea animar un TextView en un ListView sin romper las capacidades habilitadas / onFocus del textView. También se desplaza continuamente incluso si la vista no está enfocada.

Escribí el código siguiente para un ListView con los elementos del texto de la marquesina. Se basa en la solución setSelected descrita anteriormente. Básicamente, estoy extendiendo la clase ArrayAdapter y reemplazar el método getView para seleccionar el TextView antes de devolverlo:

  // Create an ArrayAdapter which selects its TextViews before returning // them. This would enable marqueeing while still making the list item // clickable. class SelectingAdapter extends ArrayAdapter<LibraryItem> { public SelectingAdapter( Context context, int resource, int textViewResourceId, LibraryItem[] objects ) { super(context, resource, textViewResourceId, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); TextView textview = (TextView) view.findViewById( R.id.textview_playlist_item_title ); textview.setSelected(true); textview.setEnabled(true); textview.setFocusable(false); textview.setTextColor(0xffffffff); return view; } } 

Esta es la respuesta que aparece en la parte superior de mi búsqueda de Google, así que pensé que podría publicar una respuesta útil aquí ya que luchar con recordar esto con bastante frecuencia. De todos modos, esto funciona para mí y requiere atributos XML y A un onFocusChangeListener.

 //XML <TextView android:id="@+id/blank_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:layout_gravity="center_horizontal|center_vertical" android:background="#a4868585" android:textColor="#fff" android:textSize="15sp" android:singleLine="true" android:lines="1" android:ellipsize="marquee" android:marqueeRepeatLimit ="marquee_forever" android:scrollHorizontally="true" android:focusable="true" android:focusableInTouchMode="true" tools:ignore="Deprecated" /> //JAVA titleText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { titleText.setSelected(true); } } }); 
  • Verticalmente Centro TextView en RelativeLayout
  • El color negro viene en cambio un fondo transparente para textview en android
  • Prensa larga sobre el texto seleccionado en textview en android
  • ¿Cómo puedo cambiar la parte del color de un TextView?
  • XAMARIN (C #) - ¿Hay una manera de subrayar un TextView mediante programación?
  • El salto de línea en Android agrega relleno
  • Mostrar vista en toda mi aplicación
  • Cambio de color de TextView en el enfoque / presione
  • Disposición de Android: Envuelva dos vistas de texto
  • Android: ¿Cómo determinar el índice de caracteres de la posición de un evento táctil en TextView?
  • Android: crea TextView (o EditText) de forma programática y lo configura en un lugar específico de la pantalla dando coordenadas
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.