Crea un'animation cambiando l'image in ImageView con timer (o gestore)

Vorrei creare un'animation semplice cambiando i fotogrammi all'interno di un ImageView. Non voglio usare AnimationDrawable perché ho bisogno di ricevere events quando un fotogramma è cambiato o quando l'animation è stata arrestata, per poter riprodurla all'indietro, riavviala e così via.

Il mio problema è che i frame non cambiano effettivamente l'evento se il setImageDrawable viene chiamato (sul thread principale). Così each cosa sembra funzionare bene tranne che i fotogrammi non cambiano (in realtà solo un fotogramma è disegnato, il primo).

  • ERRORE: Imansible leggere la row 0, col -1 da CursorWindow. Assicurarsi che il cursore sia inizializzato correttamente prima di accedere ai dati
  • Come riparare questo errore? “Java.lang.IndexOutOfBoundsException”
  • Ottieni l'indirizzo della mappa o l'indirizzo di località in Android
  • impostare il text di ListView nel centro - android
  • Classi di class personalizzata per caricamento / dominio Android-nativo
  • Scorri la vista per la visualizzazione di text in android
  • Quindi il mio codice:

    public class AnimatedImageView extends ImageView implements Animatable, Runnable { private static final String TAG = "AnimatedImageView"; public static interface AnimationEventsListener { void animationDidChangeFrame(AnimatedImageView animatedImageView); void animationDidStop(AnimatedImageView animatedImageView); } /* frames - ress ids */ private int[] mFrameResIds; /* current frame index */ private int mCurrentFrameIdx; /* number of the current repeat */ private int loopIndex; /* number of animation repetiotions, 0 for infinite */ private int mNumOfRepetitions; /* if animation is playing */ private boolean playing; /* if animation is paused */ private boolean paused; /* if animation is playing backward */ private boolean playItBackward; /* animation duration */ private long mAnimationDuration; /* frame animation duration (mAnimationDuration / num_of_frames) */ private long mFrameAnimationDuration; /* listener for animation events */ private AnimationEventsListener mListener; private Handler mHandler; public AnimatedImageView(Context context) { super(context); setup(); } public AnimatedImageView(Context context, AttributeSet attrs) { super(context, attrs); setup(); } public AnimatedImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setup(); } private void setup() { mHandler = new Handler(Looper.getMainLooper()); this.setClickable(true); Logger.d("MSG", "setup, thread: " + Thread.currentThread().toString()); } @Override public void start() { if (playing) { return; } mCurrentFrameIdx = playItBackward ? mFrameResIds.length - 1 : 0; loopIndex = 0; playing = true; updateFrame(); } @Override public void stop() { paused = true; } public void resume() { paused = false; playing = true; updateFrame(); } @Override public boolean isRunning() { return false; } @Override public void run() { Logger.d("MSG", "run, thread: " + Thread.currentThread().toString()); updateFrame(); } public AnimationEventsListener getListener() { return mListener; } public void setListener(AnimationEventsListener mListener) { this.mListener = mListener; } public long getAnimationDuration() { return mAnimationDuration; } public void setAnimationDuration(long mAnimationDuration) { this.mAnimationDuration = mAnimationDuration; if (mFrameResIds != null) { mFrameAnimationDuration = mAnimationDuration / mFrameResIds.length; } } public int[] getFrameResIds() { return mFrameResIds; } public void setFrameResIds(int[] mFrameResIds) { this.mFrameResIds = mFrameResIds; if (mFrameResIds != null) { mFrameAnimationDuration = mAnimationDuration / mFrameResIds.length; } } private void setCurrentFrame(int frameValue) { mCurrentFrameIdx = frameValue; this.setAnimationFrame(frameValue); } private void setAnimationFrame(int animationFrame) { Logger.d("MSG", "setAnimationFrame: " + animationFrame); if (animationFrame < 0) { animationFrame = 0; } if (animationFrame > -1) { animationFrame = mFrameResIds.length - 1; } Resources resources = getResources(); AnimatedImageView.this.setImageDrawable(resources.getDrawable(mFrameResIds[animationFrame])); AnimatedImageView.this.forceLayout(); // AnimatedImageView.this.setImageBitmap(BitmapFactory.decodeResource(resources, mFrameResIds[animationFrame])); // this.setImageResource(mFrameResIds[animationFrame]); AnimatedImageView.this.invalidate(); } private void updateFrame() { Logger.d("MSG", "updateFrame " + mCurrentFrameIdx); if (!playing || paused) { return; } playing = false; if (mListener != null) { mListener.animationDidChangeFrame(AnimatedImageView.this); } if (!playItBackward) { mCurrentFrameIdx++; if (mCurrentFrameIdx >= mFrameResIds.length) { loopIndex++; mCurrentFrameIdx = 0; if (mNumOfRepetitions == loopIndex) { if (mListener != null) { mListener.animationDidStop(AnimatedImageView.this); } return; } } } else { mCurrentFrameIdx--; if (mCurrentFrameIdx < 0) { loopIndex++; mCurrentFrameIdx = mFrameResIds.length - 1; if (mNumOfRepetitions == loopIndex) { if (mListener != null) { mListener.animationDidStop(AnimatedImageView.this); } return; } } } playing = true; setAnimationFrame(mCurrentFrameIdx); // mHandler.postDelayed(AnimatedImageView.this, mFrameAnimationDuration); // scheduleDrawable(getResources().getDrawable(mFrameResIds[mCurrentFrameIdx]), AnimatedImageView.this, mFrameAnimationDuration); // postDelayed() postDelayed(AnimatedImageView.this, mFrameAnimationDuration); // SongPlayerActivity.handler.postDelayed(AnimatedImageView.this, mFrameAnimationDuration); } 

    Ho un object AnimatedImageView nel mio layout in xml e nella mia attività lo trovo per id e ho iniziato l'animation cliccando:

     final AnimatedImageView mDriverAnimation = (AnimatedImageView) findViewById(R.id.driver); mDriverAnimation.setFrameResIds(new int[]{R.drawable.song1_driver1, R.drawable.song1_driver2, R.drawable.song1_driver3}); mDriverAnimation.setAnimationDuration(3 * 1000); mDriverAnimation.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { mDriverAnimation.start(); } }); 

    Qualche idea? 🙂 Grazie.

  • Impostazione della trasparenza per lo background del widget
  • Differenti comportmenti di XmlPullParser.getInputEncoding () su API11 + e le versioni pre-API11 di Android
  • Le impostazioni dello sviluppatore di Android 4.2 non sono ancora disponibili
  • Come generare R.java
  • Risorsa strings.xml di Android - linguaggio arabo e stringhe dinamiche formattate
  • Xamarin Android QR-Image ZXing - Non funziona
  • One Solution collect form web for “Crea un'animation cambiando l'image in ImageView con timer (o gestore)”

    Penso che TransitionDrawable potrebbe risolvere il problema: http://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html

     Drawable[] layers = new Drawable[2]; layers[0] = //your first drawable layers[1] = //your second drawable TransitionDrawable transition = new TransitionDrawable(layers); myImageView.setImageDrawable(transition); transition.startTransition(1500); 

    i crediti vanno a: https://stackoverflow.com/a/7973554/2673005

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.