Android se fane et se fane avec ImageView

J’ai des problèmes avec un diaporama que je construis.

J’ai créé 2 animations en XML pour le fondu entrant et sortant:

fadein.xml

    

fadeout.xml

      

Ce que je veux faire, c’est changer les images d’un ImageView en utilisant l’effet de fondu, de sorte que l’image actuellement affichée disparaîtra et qu’une autre s’affichera. problème, avec ceci:

  Animation fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.your_fade_in_anim); imageView.startAnimation(fadeoutAnim); 

Mais ensuite, je mets l’image suivante à afficher:

  imageView.setImageBitmap(secondImage); 

Il apparaît juste dans l’imageView, et quand je configure l’animation, il cache l’image, le fade en … Y a-t-il un moyen de résoudre ce problème, je veux dire, quand je fais imageView.setImageBitmap (secondImage); commande, l’image ne s’affiche pas immédiatement, et uniquement lorsque l’animation en fondu est exécutée?

Pour l’implémenter comme vous l’avez commencé, vous devrez append un AnimationListener afin de pouvoir détecter le début et la fin d’une animation. Lorsque onAnimationEnd () est appelé pour le fondu sortant, vous pouvez définir la visibilité de votre object ImageView sur View.INVISIBLE, changer les images et démarrer votre fondu dans l’animation – vous aurez également besoin d’un autre AnimationListener ici. Lorsque vous recevez onAnimationEnd () pour votre fondu dans l’animation, définissez ImageView sur View.VISIBLE et cela vous donnera l’effet recherché.

J’ai déjà mis en œuvre un effet similaire, mais j’ai utilisé un ViewSwitcher avec 2 ImageViews plutôt qu’un seul ImageView. Vous pouvez définir les animations “in” et “out” pour ViewSwitcher avec votre fondu entrant et sortant afin de pouvoir gérer l’implémentation d’AnimationListener. Il vous suffit ensuite d’alterner entre les 2 ImageViews.

Edit: Pour être un peu plus utile, voici un exemple rapide d’utilisation de ViewSwitcher. J’ai inclus la source complète sur https://github.com/aldryd/imageswitcher .

activity_main.xml

      

MainActivity.java

  // Let the ViewSwitcher do the animation listening for you ((ViewSwitcher) findViewById(R.id.switcher)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ViewSwitcher switcher = (ViewSwitcher) v; if (switcher.getDisplayedChild() == 0) { switcher.showNext(); } else { switcher.showPrevious(); } } }); 

Je voulais atteindre le même objective que vous, donc j’ai écrit la méthode suivante qui fait exactement cela si vous lui transmettez une ImageView et une liste de références à des tableaux à dessiner.

 ImageView demoImage = (ImageView) findViewById(R.id.DemoImage); int imagesToShow[] = { R.drawable.image1, R.drawable.image2,R.drawable.image3 }; animate(demoImage, imagesToShow, 0,false); private void animate(final ImageView imageView, final int images[], final int imageIndex, final boolean forever) { //imageView <-- The View which displays the images //images[] <-- Holds R references to the images to display //imageIndex <-- index of the first image to show in images[] //forever <-- If equals true then after the last image it starts all over again with the first image resulting in an infinite loop. You have been warned. int fadeInDuration = 500; // Configure time values here int timeBetween = 3000; int fadeOutDuration = 1000; imageView.setVisibility(View.INVISIBLE); //Visible or invisible by default - this will apply when the animation ends imageView.setImageResource(images[imageIndex]); Animation fadeIn = new AlphaAnimation(0, 1); fadeIn.setInterpolator(new DecelerateInterpolator()); // add this fadeIn.setDuration(fadeInDuration); Animation fadeOut = new AlphaAnimation(1, 0); fadeOut.setInterpolator(new AccelerateInterpolator()); // and this fadeOut.setStartOffset(fadeInDuration + timeBetween); fadeOut.setDuration(fadeOutDuration); AnimationSet animation = new AnimationSet(false); // change to false animation.addAnimation(fadeIn); animation.addAnimation(fadeOut); animation.setRepeatCount(1); imageView.setAnimation(animation); animation.setAnimationListener(new AnimationListener() { public void onAnimationEnd(Animation animation) { if (images.length - 1 > imageIndex) { animate(imageView, images, imageIndex + 1,forever); //Calls itself until it gets to the end of the array } else { if (forever){ animate(imageView, images, 0,forever); //Calls itself to start the animation all over again in a loop if forever = true } } } public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } }); } 

Avez-vous pensé à utiliser TransitionDrawable au lieu d’animations personnalisées? https://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html

Une façon de réaliser ce que vous recherchez est:

 // create the transition layers Drawable[] layers = new Drawable[2]; layers[0] = new BitmapDrawable(getResources(), firstBitmap); layers[1] = new BitmapDrawable(getResources(), secondBitmap); TransitionDrawable transitionDrawable = new TransitionDrawable(layers); imageView.setImageDrawable(transitionDrawable); transitionDrawable.startTransition(FADE_DURATION); 

Basé sur la solution d’Aladin Q, voici une fonction d’aide que j’ai écrite, qui changera l’image dans une imageview tout en exécutant un petit fondu en sortie / fondu dans l’animation:

 public static void ImageViewAnimatedChange(Context c, final ImageView v, final Bitmap new_image) { final Animation anim_out = AnimationUtils.loadAnimation(c, android.R.anim.fade_out); final Animation anim_in = AnimationUtils.loadAnimation(c, android.R.anim.fade_in); anim_out.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { v.setImageBitmap(new_image); anim_in.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) {} @Override public void onAnimationEnd(Animation animation) {} }); v.startAnimation(anim_in); } }); v.startAnimation(anim_out); } 

J’ai utilisé l’animation fadeIn utilisée pour remplacer la nouvelle image par une ancienne

 ObjectAnimator.ofFloat(imageView, View.ALPHA, 0.2f, 1.0f).setDuration(1000).start(); 

Le meilleur et le plus simple, pour moi, c’était ça ..

-> Créez simplement un thread avec Handler contenant sleep ().

 private ImageView myImageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shape_count); myImageView= (ImageView)findViewById(R.id.shape1); Animation myFadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fadein); myImageView.startAnimation(myFadeInAnimation); new Thread(new Runnable() { private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { Log.w("hendler", "recived"); Animation myFadeOutAnimation = AnimationUtils.loadAnimation(getBaseContext(), R.anim.fadeout); myImageView.startAnimation(myFadeOutAnimation); myImageView.setVisibility(View.INVISIBLE); } }; @Override public void run() { try{ Thread.sleep(2000); // your fadein duration }catch (Exception e){ } handler.sendEmptyMessage(1); } }).start(); } 

J’utilise ce genre de routine pour chaîner des animations par programmation.

  final Animation anim_out = AnimationUtils.loadAnimation(context, android.R.anim.fade_out); final Animation anim_in = AnimationUtils.loadAnimation(context, android.R.anim.fade_in); anim_out.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { //////////////////////////////////////// // HERE YOU CHANGE YOUR IMAGE CONTENT // //////////////////////////////////////// //ui_image.setImage... anim_in.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) {} @Override public void onAnimationEnd(Animation animation) {} }); ui_image.startAnimation(anim_in); } }); ui_image.startAnimation(anim_out); 

vous pouvez le faire par deux points simples et changer dans votre code

1.Dans votre dossier xml dans anim de votre projet, définissez la durée du fondu entrant et sortant sans être égale

2.Dans votre classe java avant le début de l’animation de sortie, définissez la deuxième visibilité de l’imageView. Après l’animation de la sortie en fondu, définissez la deuxième visibilité de l’image que vous souhaitez afficher.

fadeout.xml

  

fadein.xml

  

Dans ta classe java

 Animation animFadeOut = AnimationUtils.loadAnimation(this, R.anim.fade_out); ImageView iv = (ImageView) findViewById(R.id.imageView1); ImageView iv2 = (ImageView) findViewById(R.id.imageView2); iv.setVisibility(View.VISIBLE); iv2.setVisibility(View.GONE); animFadeOut.reset(); iv.clearAnimation(); iv.startAnimation(animFadeOut); Animation animFadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in); iv2.setVisibility(View.VISIBLE); animFadeIn.reset(); iv2.clearAnimation(); iv2.startAnimation(animFadeIn); 

C’est probablement la meilleure solution que vous obtiendrez. Simple et facile. Je l’ai appris sur udemy. Supposons que vous ayez deux images ayant l’identifiant de l’image id1 et id2 respectivement et que la vue de l’image est actuellement définie comme id1 et que vous souhaitez la remplacer par une autre image à chaque fois que quelqu’un clique MainActivity.java

 int clickNum=0; public void click(View view){ clickNum++; ImageView a=(ImageView)findViewById(R.id.id1); ImageView b=(ImageView)findViewById(R.id.id2); if(clickNum%2==1){ a.animate().alpha(0f).setDuration(2000); //alpha controls the transpiracy } else if(clickNum%2==0){ b.animate().alpha(0f).setDuration(2000); //alpha controls the transpiracy } } 

J’espère que cela aidera sûrement

Pour l’infini Fade In et Out

 AlphaAnimation fadeIn=new AlphaAnimation(0,1); AlphaAnimation fadeOut=new AlphaAnimation(1,0); final AnimationSet set = new AnimationSet(false); set.addAnimation(fadeIn); set.addAnimation(fadeOut); fadeOut.setStartOffset(2000); set.setDuration(2000); imageView.startAnimation(set); set.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { imageView.startAnimation(set); } });