Android fade in et fade out avec ImageView
J'ai quelques problèmes avec un diaporama que je construis.
J'ai créé 2 animations en xml pour fade in et fade out:
Fadein.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:duration="2000"/>
</set>
Fadeout.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:duration="2000"/>
</set>
Ce que je cherche à faire, c'est de changer les images d'un ImageView en utilisant l'effet de fondu, de sorte que l'image actuellement affichée disparaîtra, et une autre disparaîtra. Considérant que j'ai déjà une image définie, je peux effacer cette Image sans problème, avec ce:
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 s'affiche dans la imageView, et quand je l'animation il cache l'image, la en fondu... Est - il possible 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 seulement lorsque le fondu dans l'animation est exécuté?
10 réponses
Pour l'implémenter comme vous l'avez commencé, vous devrez ajouter un AnimationListener afin de détecter le début et la fin d'une animation. Lorsque onAnimationEnd() pour le fondu est appelé, vous pouvez définir la visibilité de votre objet ImageView sur View.INVISIBLE, changez les images et commencez votre fondu dans l'animation-vous aurez besoin d'un autre AnimationListener ici aussi. Lorsque vous recevez onAnimationEnd () pour votre fondu dans l'animation, définissez ImageView sur View.Le VISIBLE et l' devrait vous donner l'effet que vous recherchez.
J'ai déjà implémenté 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 fade in et fade out afin qu'il puisse gérer L'implémentation AnimationListener. Ensuite, tout ce que vous devez faire est d'alterner entre les 2 ImageViews.
Modifier: Pour être un peu plus utile, voici un rapide exemple d'utilisation de la ViewSwitcher. J'ai inclus la source à https://github.com/aldryd/imageswitcher.
Activity_main.xml
<ViewSwitcher
android:id="@+id/switcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:inAnimation="@anim/fade_in"
android:outAnimation="@anim/fade_out" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="@drawable/sunset" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="@drawable/clouds" />
</ViewSwitcher>
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 objectif que vous, alors j'ai écrit la méthode suivante qui fait exactement cela si vous lui passez un ImageView et une liste de références à image drawables.
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 cherchez 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 va changer l'image dans un imageview tout en exécutant un petit fondu / 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 l'ancienne
ObjectAnimator.ofFloat(imageView, View.ALPHA, 0.2f, 1.0f).setDuration(1000).start();
Le meilleur et le plus facile, pour moi, c'était ça..
- > créez simplement un thread avec un gestionnaire 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 enchaîner les 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 votre code
1.In votre xml dans le dossier anim de votre projet, définissez la durée fade in et fade out non égale
2.In vous classe java avant le début de l'animation fade out, définissez la deuxième visibilité imageView puis après le démarrage de l'animation fade out définissez la deuxième visibilité imageView que vous voulez fondu dans visible
Fadeout.xml
<alpha
android:duration="4000"
android:fromAlpha="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="0.0" />
Fadein.xml
<alpha
android:duration="6000"
android:fromAlpha="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="1.0" />
Dans vous 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 respectivement id1 et id2 d'ID d'image et que la vue de l'image soit définie comme id1 et que vous souhaitiez la changer en l'autre image chaque fois que quelqu'un clique dessus. C'est donc le code de base dans MainActivity.java
File
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 va sûrement aider
Pour infini fondu dans et Hors
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);
}
});