Android fade in dan fade out dengan ImageView

89

Saya mengalami masalah dengan tayangan slide yang sedang saya buat.

Saya telah membuat 2 animasi dalam xml untuk fade in dan 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>

Apa yang Saya coba lakukan, adalah mengubah gambar dari ImageView menggunakan efek fade, sehingga gambar yang sedang ditampilkan akan memudar, dan gambar lain akan memudar. Mengingat saya memiliki gambar yang sudah disetel, saya dapat memudarkan Gambar ini tanpa masalah, dengan ini:

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

Tapi kemudian, saya mengatur gambar berikutnya untuk ditampilkan:

    imageView.setImageBitmap(secondImage);

Itu hanya muncul di imageView, dan ketika saya mengatur animasi itu menyembunyikan gambar, memudarnya masuk ... Apakah ada cara untuk memperbaikinya, maksud saya, ketika saya melakukan imageView.setImageBitmap (secondImage); perintah, gambar tidak segera muncul, dan hanya jika animasi fade in dijalankan?

IPValverde
sumber

Jawaban:

66

Untuk mengimplementasikan ini seperti Anda memulai, Anda perlu menambahkan AnimationListener sehingga Anda bisa mendeteksi awal dan akhir animasi. Saat onAnimationEnd () untuk fade out dipanggil, Anda dapat menyetel visibilitas objek ImageView Anda ke View.INVISIBLE, mengganti gambar dan memulai animasi fade in - Anda juga memerlukan AnimationListener lain di sini. Saat Anda menerima onAnimationEnd () untuk animasi fade in Anda, setel ImageView menjadi View.VISIBLE dan itu akan memberi Anda efek yang Anda cari.

Saya telah menerapkan efek serupa sebelumnya, tapi saya menggunakan ViewSwitcher dengan 2 ImageView daripada satu ImageView. Anda dapat menyetel animasi "masuk" dan "keluar" untuk ViewSwitcher dengan fade in dan fade out sehingga dapat mengelola implementasi AnimationListener. Kemudian yang perlu Anda lakukan adalah bergantian antara 2 ImageView.

Edit: Agar sedikit lebih berguna, berikut adalah contoh singkat tentang cara menggunakan ViewSwitcher. Saya telah menyertakan sumber lengkapnya di 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();
            }
        }
    });
Aldryd
sumber
Terima kasih sobat! Saya lupa tentang serVisible! Dan terima kasih atas tip ViewSwitcher, tampaknya lebih mudah daripada menangani semuanya sendiri.
IPValverde
@Aldryd Apakah ini lebih efisien dari segi kinerja? Dibandingkan dengan jawaban yang dipilih (file XML terpisah)?
Ron
@Ron Saya tidak benar-benar membandingkan kinerja metode yang berbeda. Dibandingkan dengan decoding / bekerja dengan bitmap untuk objek ImageView, menurut saya, menggunakan ViewSwitcher versus mengimplementasikan AnimationListener sendiri tidak akan terlalu terlihat. Saya baru-baru ini mengetahui bahwa jika Anda menggunakan API 11 atau lebih tinggi, Anda dapat menggunakan beberapa kelas Animasi baru. Anda dapat melihat contoh crossfading 2 tampilan dengan API 11 di sini: developer.android.com/training/animation/crossfade.html
Aldryd
96

Saya ingin mencapai tujuan yang sama seperti Anda, jadi saya menulis metode berikut yang melakukan persis seperti itu jika Anda meneruskan ImageView dan daftar referensi ke gambar yang dapat digambar.

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
        }
    });
}
Buaya
sumber
1
Untuk menunjukkan bagaimana animasi fade in dan out dapat didefinisikan dalam kode, Anda tuan, dapatkan suara saya
Herr Grumps
Anda juga dapat menghitung pengulangan dan menghitung% Array.lenght dalam metode
onAnimationRepeat
2
@Crocodile Apakah menurut Anda mungkin ada masalah memori dalam kode Anda. Biarkan aktivitas dengan kode di atas terus berjalan. Ini akan membuat begitu banyak Objek AnimationSet. Apakah ada kemungkinan bahwa itu akan crash dengan outOfMemory setelah beberapa waktu?
Permata
1
Anda tuan adalah penyelamat!
faizanjehangir
2
@ Permata - mengapa alokasi khusus itu menyebabkan masalah? Setiap kali imageView.setAnimation (animasi) dipanggil, referensi apa pun ke animasi sebelumnya hilang, sehingga pengumpul sampah akan dapat menghapus objek sebelumnya ini. AFAIK, bukan masalah memori.
greg7gkb
46

Pernahkah Anda berpikir untuk menggunakan TransitionDrawable alih-alih animasi khusus? https://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html

Salah satu cara untuk mencapai apa yang Anda cari adalah:

// 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);
munkay
sumber
2
Ini adalah jawaban terbaik untuk pertanyaan ini.
DragonT
Maaf atas benturannya, tetapi jika saya menggunakan ini di Handler, dan memilikinya dalam loop permanen, aplikasi kehilangan kinerja dalam animasi fade in / fade out konstan lainnya yang saya miliki. Ada rekomendasi?
Yakobus
TransitionDrawable hanya dapat menangani dua gambar / lapisan.
Signcodeindie
Transisi drawable menyebabkan AppNotIdleException saat menjalankan pengujian espresso
PK Gupta
6

Saya menggunakan animasi fadeIn untuk mengganti gambar baru dengan yang lama

ObjectAnimator.ofFloat(imageView, View.ALPHA, 0.2f, 1.0f).setDuration(1000).start();
Rafael
sumber
2
Lihat android-developers.blogspot.com/2011/05/… untuk kode yang lebih bersih.
zyamys
TERIMA KASIH!! masih relevan ... Yang paling aku butuhkan sekarang!
Teekam Suthar
1
Terima kasih!! Ini adalah jawaban terbaik ... sangat sederhana untuk diterapkan dan bekerja dengan lancar.
pengguna3152377
3

Berdasarkan solusi Aladin Q, berikut adalah fungsi pembantu yang saya tulis, yang akan mengubah gambar di imageview sambil menjalankan sedikit fade out / fade dalam animasi:

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);
    }
radhoo
sumber
3

Anda dapat melakukannya dengan dua titik sederhana dan mengubah kode Anda

1. Di folder xml di anim proyek Anda, Atur waktu fade in dan fade out tidak sama

2. Di kelas java Anda sebelum dimulainya animasi fade out, setel visibilitas imageView kedua. Hilang kemudian setelah animasi fade out mulai setel visibilitas imageView kedua yang ingin Anda fade in 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" />

Di kelas java kamu

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);
Hadi Samadbin
sumber
3

Untuk Fade In dan Out yang tak terbatas

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);
    }
});
Aryan Sharma
sumber
1

Saya menggunakan jenis rutinitas ini untuk merangkai animasi secara terprogram.

    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);
Aladin Q
sumber
1

Cara terbaik dan termudah, bagi saya adalah ini ..

-> Cukup buat utas dengan Handler yang berisi 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();
}
Sankar Behera
sumber
1

Ini mungkin solusi terbaik yang akan Anda dapatkan. Sederhana dan Mudah. Saya mempelajarinya di udemy. Misalkan Anda memiliki dua gambar yang masing-masing memiliki id gambar id1 dan id2 dan saat ini tampilan gambar disetel sebagai id1 dan Anda ingin mengubahnya ke gambar lain setiap kali seseorang mengklik masuk Jadi ini adalah kode dasar di MainActivity.javaFile

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
}

}

Saya harap ini pasti akan membantu

Saurabh Kumar
sumber