Contador de TextView de Android con animación Top / Down
Tenemos un TextView que me gustaría contar hacia abajo (9 … 3 … 2 … 1 … 0 o 0 … 1 … 3..6..9 cosas suceden).
Así (como cualquier medidor de tipo está trabajando):
- Animación paralela en Imageview
- Problema para lograr una animación curvada
- ¿Cómo hago pausas la animación de los cuadros usando AnimationDrawable?
- Cómo invertir la dirección de la marquesina de un TextView
- Android no anima alfa si es inicialmente cero
Para que sea un poco más interesante, quiero que cada dígito vienen de arriba a abajo o de abajo a arriba?
Ahora mismo, usando listview para lograr esto, también he intentado con TextSwitcher
pero su tiene una limitación de dos niños solamente.
Estoy usando getListView().smoothScrollToPosition(0...3...6...6...n)
;
¿Hay una manera simple de hacer esto? Porque ahora mismo, necesitamos mantener 3 ListView
y Adapter
también para mantener esto.
Por favor, consulte el enlace para entender esta pregunta.
Display StopWatch Timer animado como el medidor de gasolina con NSTimer
- Accidente con aceleración de hardware de animaciones de transición de fragmentos
- Determinar la vista que aparece en LayoutManager pre-layout
- Suavemente animar vista ocultar / mostrar en disposición lineal android
- Android Twitter - Hacer clic en la pestaña Actualizar y ocultar
- Android - Animación de zoom utilizando AnimatorSet
- Animación de diapositivas de la actividad con overridePendingTransition teniendo un efecto extraño
- Animar texto con TextSwitcher en Android
- Cómo agregar vista al diseño XML android
ListView
's podría ser la solución lo suficientemente buena, pero lo he implementado con una vista personalizada ( FrameLayout
), que contiene dentro de 2 TextView
s, que están animando en función de los cambios de valor:
La idea del código es muy básica:
- Se pasa al valor deseado
setValue
; - Si es más grande que la animación actual de un inicio de abajo hacia arriba (y viceversa) para incrementar / disminuir el valor actual de 1. Aquí,
TextView
dosTextView
a reemplazarlos; -
En el oyente de AnimationEnd, compruebe si alcanzamos el valor deseado – si no – hacer una carrera más (recursivamente);
public class DigitTextView extends FrameLayout { private static int ANIMATION_DURATION = 250; TextView currentTextView, nextTextView; public DigitTextView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public DigitTextView(Context context) { super(context); init(context); } private void init(Context context) { LayoutInflater.from(context).inflate(R.layout.digit_text_view, this); currentTextView = (TextView) getRootView().findViewById(R.id.currentTextView); nextTextView = (TextView) getRootView().findViewById(R.id.nextTextView); nextTextView.setTranslationY(getHeight()); setValue(0); } public void setValue(final int desiredValue) { if (currentTextView.getText() == null || currentTextView.getText().length() == 0) { currentTextView.setText(String.format(Locale.getDefault(), "%d", desiredValue)); } final int oldValue = Integer.parseInt(currentTextView.getText().toString()); if (oldValue > desiredValue) { nextTextView.setText(String.format(Locale.getDefault(), "%d", oldValue-1)); currentTextView.animate().translationY(-getHeight()).setDuration(ANIMATION_DURATION).start(); nextTextView.setTranslationY(nextTextView.getHeight()); nextTextView.animate().translationY(0).setDuration(ANIMATION_DURATION).setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { currentTextView.setText(String.format(Locale.getDefault(), "%d", oldValue - 1)); currentTextView.setTranslationY(0); if (oldValue - 1 != desiredValue) { setValue(desiredValue); } } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }).start(); } else if (oldValue < desiredValue) { nextTextView.setText(String.format(Locale.getDefault(), "%d", oldValue+1)); currentTextView.animate().translationY(getHeight()).setDuration(ANIMATION_DURATION).start(); nextTextView.setTranslationY(-nextTextView.getHeight()); nextTextView.animate().translationY(0).setDuration(ANIMATION_DURATION).setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { currentTextView.setText(String.format(Locale.getDefault(), "%d", oldValue + 1)); currentTextView.setTranslationY(0); if (oldValue + 1 != desiredValue) { setValue(desiredValue); } } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }).start(); } } }
Y es XML:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="48dp" android:layout_height="56dp" android:padding="8dp" android:background="@drawable/rounded_blue_rect"> <TextView android:id="@+id/currentTextView" android:textColor="#FFFFFF" android:textSize="18sp" android:gravity="center" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/nextTextView" android:textColor="#FFFFFF" android:textSize="18sp" android:layout_gravity="center" android:gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </FrameLayout>
Y es muy fácil de usar:
Añadir al diseño:
<klogi.com.myapplication.DigitTextView android:id="@+id/digitTextView" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
Y establecer Valor en código:
DigitTextView digitTextView = (DigitTextView) findViewById(R.id.digitTextView); digitTextView.setValue(5);
Actualización:
Otra opción a utilizar, por lo que veo, es configurar un número personalizado NumberPicker
¡Espero que ayude!
Desde Robinhood ganó los premios de diseño de materiales que han abierto de origen allí TextView
personalizado al igual que usted está describiendo.
Echa un vistazo a la biblioteca de Robinhood's Ticker
También puede utilizar un controlador para obtener el efecto deseado. Usando esto, no tendrá que hacer ninguna vista personalizada. Cree una función handleTextView que toma inicialValue , finalValue y targetTextview como argumentos. El método es-
private void handleTextView(int initialValue, int finalValue, final TextView targetTextview) { DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(1f); final int newInitialValue = Math.min(initialValue, finalValue); final int newFinalValue = Math.max(initialValue, finalValue); final int difference = Math.abs(finalValue - initialValue); Handler handler = new Handler(); for (int count = newInitialValue; count <= newFinalValue; count++) { //Time to display the current value to the user. int time = Math.round(decelerateInterpolator.getInterpolation((((float) count) / difference)) * 100) * count; final int finalCount = ((initialValue > finalValue) ? initialValue - count : count); handler.postDelayed(new Runnable() { @Override public void run() { targetTextview.setText(finalCount.toString()); } }, time); } }
UPDATE: Opción 2 – También puede utilizar un animador de valores –
private void handleTextView(int initialValue, int finalValue, final TextView textview) { ValueAnimator valueAnimator = ValueAnimator.ofInt(initialValue, finalValue); valueAnimator.setDuration(1500); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { textview.setText(valueAnimator.getAnimatedValue().toString()); } }); valueAnimator.start(); }
Usando este método no necesitamos hacer ninguna matemática.