Fragmen dan animasi Android

265

Bagaimana seharusnya Anda menerapkan jenis geser yang misalnya digunakan klien Honeycomb Gmail?

Dapat TransactionManagermenangani ini secara otomatis dengan menambahkan dan menghapus Fragmen, agak sulit untuk menguji ini karena emulator menjadi slideshow :)

alexanderblom
sumber

Jawaban:

388

Untuk menghidupkan transisi antara fragmen, atau untuk menghidupkan proses memperlihatkan atau menyembunyikan fragmen yang Anda gunakan Fragment Manageruntuk membuat a Fragment Transaction.

Dalam setiap Transaksi Fragmen, Anda dapat menentukan animasi masuk dan keluar yang akan digunakan untuk acara dan sembunyikan masing-masing (atau keduanya ketika penggantian digunakan).

Kode berikut menunjukkan bagaimana Anda akan mengganti sebuah fragmen dengan menggeser satu fragmen dan menggeser yang lainnya di tempatnya.

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);

DetailsFragment newFragment = DetailsFragment.newInstance();

ft.replace(R.id.details_fragment_container, newFragment, "detailFragment");

// Start the animated transition.
ft.commit();

Untuk mencapai hal yang sama dengan menyembunyikan atau menampilkan sebuah fragmen, Anda cukup memanggil ft.showatau ft.hide, mengirimkan fragmen yang ingin Anda perlihatkan atau sembunyikan masing-masing.

Untuk referensi, definisi animasi XML akan menggunakan objectAnimatortag. Contoh slide_in_left mungkin terlihat seperti ini:

<?xml version="1.0" encoding="utf-8"?>
<set>
  <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="x" 
    android:valueType="floatType"
    android:valueFrom="-1280"
    android:valueTo="0" 
    android:duration="500"/>
</set>
Reto Meier
sumber
57
Ketika saya mencoba ini menunjukkan RuntimeException: Nama animator tidak dikenal: terjemahkan .
Labeeb Panampullan
3
Pastikan animasi yang didefinisikan dalam slide_in_left dan kanan dibuat menggunakan sekumpulan definisi objectAnimator daripada definisi animasi yang lama.
Reto Meier
7
Itu sangat membantu. Saya berada di jalur yang benar tetapi tidak sampai ke sana. Untuk pembaca lain, Anda juga dapat memiliki android: interpolator sebagai atribut, dengan yang favorit Anda ditentukan (seperti "@android: interpolator / linear"). Standarnya adalah "@android: interpolator / accelerate_decelerate".
Dave MacLean
6
Saya menargetkan API Level 7 dengan API yang kompatibel. Apakah ada cara bagi saya untuk menghidupkan fragmen?
Jarrod Smith
5
@JarrodSmith Anda dapat mencoba menggunakan perpustakaan kompatibilitas seperti NineOldAndroids untuk membawa API Honeycomb ke Eclair.
Tn. S
249

Jika Anda tidak harus menggunakan perpustakaan dukungan, lihat jawaban Roman .

Tetapi jika Anda ingin menggunakan pustaka dukungan Anda harus menggunakan kerangka animasi lama seperti yang dijelaskan di bawah ini.

Setelah berkonsultasi dengan jawaban Reto dan blindstuff, saya membuat kode berikut berfungsi.

Fragmen tampak meluncur masuk dari kanan dan meluncur keluar ke kiri saat kembali ditekan.

FragmentManager fragmentManager = getSupportFragmentManager();

FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);

CustomFragment newCustomFragment = CustomFragment.newInstance();
transaction.replace(R.id.fragment_container, newCustomFragment );
transaction.addToBackStack(null);
transaction.commit();

Urutan itu penting. Ini berarti Anda harus menelepon setCustomAnimations()sebelum replace()atau animasi tidak akan berpengaruh!

Selanjutnya file-file ini harus ditempatkan di dalam folder res / anim .

enter.xml :

<?xml version="1.0" encoding="utf-8"?>
<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="100%"
               android:toXDelta="0"
               android:interpolator="@android:anim/decelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

exit.xml :

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="0"
               android:toXDelta="-100%"
               android:interpolator="@android:anim/accelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_enter.xml :

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="-100%"
               android:toXDelta="0"
               android:interpolator="@android:anim/decelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_exit.xml :

<?xml version="1.0" encoding="utf-8"?>
<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="0"
               android:toXDelta="100%"
               android:interpolator="@android:anim/accelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

Durasi animasi dapat diubah ke nilai default @android:integer/config_shortAnimTimeapa saja seperti atau nomor lainnya.

Perhatikan bahwa jika di antara penggantian fragmen terjadi perubahan konfigurasi (misalnya rotasi) aksi kembali tidak dianimasikan. Ini adalah bug yang didokumentasikan yang masih ada di rev 20 pustaka dukungan.

dmanargias
sumber
47
Ini baru saja menyelamatkan saya. Catatan, perhatikan pesanan itu penting , yang, tentu saja, saya ketinggalan pertama kali. Ini berarti Anda harus memanggil setCustomAnimations () sebelum mengganti ().
Stephen Kidson
3
Saya mencoba menerapkan pada fragmen saya. Saya menulis semuanya seperti yang Anda sebutkan, tetapi logcat berkata: unknown animator menerjemahkan nama Bagaimana saya bisa mengatasi masalah ini? Ngomong-ngomong, saya menelepon bagian saya di Navigasi Laci (Menu Geser)
Zafer Celaloglu
Berfungsi bagus tetapi ternyata membangun ini dengan alat bangun 21.1 menghasilkan kesalahan yang mengatakan "Nama file tidak valid: harus mengandung hanya huruf kecil dan digit ([a-z0-9_.]))". Saya menyarankan untuk mengedit nama file dalam jawaban ke pop_enter.xml dan pop_exit.xml.
smichak
Solusi hebat dan bekerja sangat baik ketika saya menekan tombol kembali. Saya hanya punya satu pertanyaan: Jika saya ingin membuat backButton khusus, kode apa yang harus saya panggil untuk mereplikasi perilaku dari tombol kembali?
Thomas Teilmann
1
Thomas jika Anda ingin kembali, Anda harus menerapkan formulir ini: .setCustomAnimations (R.anim.pop_enter, R.anim.pop_exit, R.anim.enter, R.anim.exit)
Alex Zaraos
26

Saya sangat menyarankan Anda menggunakan ini daripada membuat file animasi karena ini adalah solusi yang jauh lebih baik. Android Studio sudah menyediakan standar animation yang dapat Anda gunakan tanpa membuat file XML baru. Nama animasinya adalah android.R.anim.slide_in_left dan android.R.anim.slide_out_right dan Anda dapat menggunakannya sebagai berikut:

fragmentTransaction.setCustomAnimations (android.R.anim.slide_in_left, android.R.anim.slide_out_right);

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();              
fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
fragmentManager.addOnBackStackChangedListener(this);
fragmentTransaction.replace(R.id.frame, firstFragment, "h");
fragmentTransaction.addToBackStack("h");
fragmentTransaction.commit();

Keluaran:

masukkan deskripsi gambar di sini

Gowthaman M
sumber
1
android.R ... "Android Studio Menyediakan animasi default", itu bukan untuk android studio, ia dapat bekerja di gerhana juga, android.R adalah android spesifik. Dan omong-omong Anda tidak membagikan informasi apa yang dimiliki apis ini. Karena hal-hal di android.R berbeda pada apis yang berbeda.
steve moretz
@stevemoretz thaxs bro Saya menyetujui poin Anda .. Saya akan memperbaiki dan memperbarui jawaban saya ...
Gowthaman M
5

Pustaka dukungan yang dimodifikasi saya mendukung penggunaan animasi Tampilan (mis. <translate>, <rotate>) Dan Animator Obyek (mis. <objectAnimator>) Untuk Transisi Fragmen. Ini diimplementasikan dengan NineOldAndroids . Lihat dokumentasi saya di github untuk detailnya.

mark.kedzierski
sumber
2

Sedangkan untuk saya, saya perlu diraction view:

di -> geser dari kanan

keluar -> geser ke kiri

Di sini berfungsi untuk saya:

slide_in_right.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="50%p" android:toXDelta="0"
            android:duration="@android:integer/config_mediumAnimTime"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

slide_out_left.xml

 <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromXDelta="0" android:toXDelta="-50%p"
                android:duration="@android:integer/config_mediumAnimTime"/>
        <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
                android:duration="@android:integer/config_mediumAnimTime" />
    </set>

Kode transaksi:

inline fun FragmentActivity.setContentFragment(
        containerViewId: Int,
        backStack: Boolean = false,
        isAnimate: Boolean = false,
        f: () -> Fragment

): Fragment? {
    val manager = supportFragmentManager
    return f().apply {
        manager.beginTransaction().let {
            if (isAnimate)
                it.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)

            if (backStack) {
                it.replace(containerViewId, this, "Fr").addToBackStack("Fr").commit()
            } else {
                it.replace(containerViewId, this, "Fr").commit()
            }
        }
    }
}
Serg Burlaka
sumber
Android tampaknya
mengedipkan
@GabrielDeOliveiraRohden bagi saya tidak dalam semua kaset
Serg Burlaka
1

Saya menyelesaikan ini dengan cara di bawah ini

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment
Shakawat Hossain
sumber