Cara menghentikan animasi (batal () tidak berfungsi)

244

Saya harus menghentikan animasi terjemahan yang sedang berjalan. The .cancel()metode Animationtidak berpengaruh; animasi berjalan sampai akhir.

Bagaimana Anda membatalkan animasi yang sedang berjalan?

Campuran
sumber

Jawaban:

508

Panggil clearAnimation()mana saja yang ViewAnda panggil startAnimation().

CommonsWare
sumber
Tetapi sebenarnya saya memerlukan hal yang sedikit lebih rumit: ketika animasi berhenti, itu harus tetap pada posisi saat ini, yaitu saya memiliki gambar geser dan pada acara sentuhan itu harus membeku di tempat ini. clearAnimation () bukan case, karena me-reset keadaan untuk memulai / mengakhiri posisi tergantung pada setFillAfter ()
Campur
1
@ user349871: setFillAfter()mungkin tidak melakukan apa yang Anda pikirkan. Saat acara sentuh terjadi, hapus animasi dan kemudian sesuaikan tata letak Anda untuk memengaruhi perubahan permanen apa pun yang Anda cari.
CommonsWare
Oke, bagus, saya akan mencoba menghentikan animasi dengan memanggil clearAnimation (). Langkah selanjutnya adalah menemukan posisi di mana animasi telah ada sebelum saya menghentikannya. Apa API untuk itu?
Campur
@Mix: Tidak ada API untuk itu.
CommonsWare
7
Halo lagi! Saya telah menemukan cara untuk mendapatkan poin (dalam hal waktu interpolasi) ketika animasi dibatalkan. Anda perlu membuat Animasi sub-kelas dan memasukkan kode dari animasi kode android (mis. TerjemahanAnimasi). Di kelas Anda, Anda akan dapat menyimpan dan melacak posisi dalam fungsi applyTransformation ().
Campur
40

Pada Android 4.4.4, sepertinya satu-satunya cara saya bisa menghentikan animasi alpha fading pada View sedang memanggil View.animate().cancel()(yaitu, memanggil .cancel()View's ViewPropertyAnimator).

Berikut kode yang saya gunakan untuk kompatibilitas sebelum dan sesudah ICS:

public void stopAnimation(View v) {
    v.clearAnimation();
    if (canCancelAnimation()) {
        v.animate().cancel();
    }
}

... dengan metode:

/**
 * Returns true if the API level supports canceling existing animations via the
 * ViewPropertyAnimator, and false if it does not
 * @return true if the API level supports canceling existing animations via the
 * ViewPropertyAnimator, and false if it does not
 */
public static boolean canCancelAnimation() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
}

Inilah animasi yang saya hentikan:

v.setAlpha(0f);
v.setVisibility(View.VISIBLE);
// Animate the content view to 100% opacity, and clear any animation listener set on the view.
v.animate()
    .alpha(1f)
    .setDuration(animationDuration)
    .setListener(null);
Sean Barbeau
sumber
.setListener(null);ini membantu saya.
Muhammad Saqib
18

Jika Anda menggunakan pendengar animasi, atur v.setAnimationListener(null). Gunakan kode berikut dengan semua opsi.

v.getAnimation().cancel();
v.clearAnimation();
animation.setAnimationListener(null);
DjP
sumber
2
Tidak perlu menelepon v.setAnimation(null);karena ini akan dilakukan di v.clearAnimation();.
Christian
Seperti yang dikatakan @Christian v.setAnimation (null) tidak diperlukan
akshay bhange
5

Anda harus menggunakan .clearAnimation (); metode di utas UI:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        v.clearAnimation();
    }
});
rz0
sumber
3

Apa yang dapat Anda coba lakukan adalah mendapatkan Matriks transformasi dari animasi sebelum Anda menghentikannya dan memeriksa konten Matrix untuk mendapatkan nilai posisi yang Anda cari.

Inilah api yang harus Anda perhatikan

public boolean getTransformation (long currentTime, Transformation outTransformation)

public Matrix getMatrix ()

public void getValues (float[] values)

Jadi misalnya (beberapa kode pseudo. Saya belum menguji ini):

Transformation outTransformation = new Transformation();
myAnimation.getTransformation(currentTime, outTransformation);
Matrix transformationMatrix = outTransformation.getMatrix();
float[] matrixValues = new float[9];
transformationMatrix.getValues(matrixValues);
float transX = matrixValues[Matrix.MTRANS_X];
float transY = matrixValues[Matrix.MTRANS_Y];
Akos Cz
sumber
Di mana kita mendapatkan currentTime?
mako
Oh, dokumentasi mengatakan itu sesuai dengan "jam dinding", di tempat lain mereka mendefinisikan jam dinding sebagai System.currentTimeMillis (), yang sesuai dengan waktu kalender dan akan melompat setiap kali waktu diubah oleh pengguna atau jaringan. Ukuran aneh untuk digunakan.
mako
0

Gunakan metode setAnimation (null) untuk menghentikan animasi, yang diekspos sebagai metode publik di View.java , itu adalah kelas dasar untuk semua widget , yang digunakan untuk membuat komponen UI interaktif (tombol, bidang teks, dll.). /** * Sets the next animation to play for this view. * If you want the animation to play immediately, use * {@link #startAnimation(android.view.animation.Animation)} instead. * This method provides allows fine-grained * control over the start time and invalidation, but you * must make sure that 1) the animation has a start time set, and * 2) the view's parent (which controls animations on its children) * will be invalidated when the animation is supposed to * start. * * @param animation The next animation, or null. */ public void setAnimation(Animation animation)

saurabh dhillon
sumber
0

Untuk menghentikan animasi, Anda dapat mengatur objekAnimator yang tidak melakukan apa pun, misalnya

pertama ketika membalik manual ada animasi kiri ke kanan:

flipper.setInAnimation(leftIn);
flipper.setOutAnimation(rightOut);

lalu ketika beralih ke flipping otomatis tidak ada animasi

flipper.setInAnimation(doNothing);
flipper.setOutAnimation(doNothing);

doNothing = ObjectAnimator.ofFloat(flipper, "x", 0f, 0f).setDuration(flipperSwipingDuration);
Andrew Glukhoff
sumber