Dilema: kapan harus menggunakan Fragmen vs Aktivitas:

786

Saya tahu bahwa Activitiesdirancang untuk mewakili satu layar aplikasi saya, sementara Fragmentsdirancang untuk menjadi tata letak UI yang dapat digunakan kembali dengan logika yang tertanam di dalamnya.

Sampai belum lama ini, saya mengembangkan aplikasi karena dikatakan bahwa mereka harus dikembangkan. Saya membuat sebuah Activityuntuk mewakili layar aplikasi saya dan menggunakan Fragmen untuk ViewPageratau Google Maps. Saya jarang membuat ListFragmentUI atau lainnya yang dapat digunakan kembali beberapa kali.

Baru-baru ini saya menemukan sebuah proyek yang hanya berisi 2 Activitiessatu SettingsActivitydan satu lainnya adalah MainActivity. Tata letak MainActivitydiisi dengan banyak fragmen UI layar penuh tersembunyi dan hanya satu yang ditampilkan. Dalam Activitylogikanya ada banyak FragmentTransitionsantara layar aplikasi yang berbeda.

Apa yang saya sukai dari pendekatan ini adalah karena aplikasi menggunakan ActionBar, ia tetap utuh dan tidak bergerak dengan animasi peralihan layar, yang terjadi dengan Activityperalihan. Ini memberikan nuansa yang lebih lancar untuk transisi layar tersebut.

Jadi saya kira apa yang saya tanyakan adalah membagikan cara pengembangan Anda saat ini mengenai topik ini, saya tahu itu mungkin terlihat seperti pertanyaan berdasarkan pendapat pada pandangan pertama, tetapi saya melihatnya sebagai pertanyaan desain dan arsitektur Android ... opini berdasarkan satu.

UPDATE (01.05.2014): Mengikuti presentasi ini oleh Eric Burke dari Square , (yang harus saya katakan adalah presentasi yang hebat dengan banyak alat yang berguna untuk pengembang android. Dan saya tidak memiliki hubungan apa pun dengan Square)

http://www.infoq.com/presentations/Android-Design/

Dari pengalaman pribadi saya selama beberapa bulan terakhir, saya menemukan bahwa cara terbaik untuk membangun aplikasi saya adalah dengan membuat grup fragmen yang datang untuk mewakili aliran dalam aplikasi dan menyajikan semua fragmen dalam satu aplikasi Activity. Jadi pada dasarnya Anda akan memiliki jumlah yang sama Activitiesdalam aplikasi Anda dengan jumlah arus. Dengan begitu bilah tindakan tetap utuh di semua layar aliran, tetapi sedang diciptakan ulang untuk mengubah aliran yang sangat masuk akal. Seperti yang Eric Burke nyatakan dan seperti yang saya sadari juga, filosofi menggunakan sesedikit Activitiesmungkin tidak berlaku untuk semua situasi karena itu menciptakan kekacauan dalam apa yang ia sebut aktivitas "Tuhan".

Emil Adz
sumber

Jawaban:

271

Para ahli akan memberi tahu Anda: "Ketika saya melihat UI, saya akan tahu apakah akan menggunakan Activity atau Fragment". Pada awalnya ini tidak akan masuk akal, tetapi pada waktunya, Anda benar-benar dapat mengetahui apakah Anda perlu Fragmentatau tidak.

Ada praktik baik yang menurut saya sangat membantu bagi saya. Itu terpikir oleh saya ketika saya mencoba menjelaskan sesuatu kepada putri saya.

Yaitu, bayangkan sebuah kotak yang mewakili layar. Bisakah Anda memuat layar lain di kotak ini? Jika Anda menggunakan kotak baru, apakah Anda harus menyalin beberapa item dari kotak pertama? Jika jawabannya Ya, maka Anda harus menggunakan Fragments, karena rootActivity dapat menampung semua elemen yang digandakan untuk menghemat waktu Anda dalam membuatnya, dan Anda dapat dengan mudah mengganti bagian-bagian dari kotak.

Tetapi jangan lupa bahwa Anda selalu membutuhkan wadah kotak ( Activity) atau bagian Anda akan tersebar. Jadi satu kotak dengan bagian dalam.

Berhati-hatilah agar tidak menyalahgunakan kotak. Saran ahli Android UX (Anda dapat menemukannya di YouTube) saat kami harus memuat yang lain secara eksplisit Activity, alih-alih menggunakan Fragment(seperti ketika kami berurusan dengan Drawer Navigasi yang memiliki kategori). Setelah merasa nyaman Fragments, Anda dapat menonton semua video mereka. Bahkan lebih dari itu adalah bahan wajib.

Bisakah Anda sekarang melihat UI Anda dan mencari tahu apakah Anda memerlukan Activityatau Fragment? Apakah Anda mendapatkan perspektif baru? Saya pikir kamu melakukannya.

cendana
sumber
4
apakah Anda memiliki tautan ke umpan youtube yang Anda sebutkan? Saya mencari "pakar Android UX" dan "Android UX" tetapi tidak sepenuhnya yakin video mana yang Anda bicarakan.
saya--
2
Tidak lagi, menontonnya lebih dari setahun yang lalu. Cari pejabat pengembang Android berbicara tentang UX
sandalone
1
Salah satu contoh pertimbangan: aktivitas memiliki parentActivity sehingga kami dapat mensintesis backstack saat memasukkan dari notifikasi, tapi saya rasa tidak ada parentFragment.
fikr4n
@BornToCode ada getParentFragment: developer.android.com/reference/android/support/v4/app/…
ToolmakerSteve
@ToolmakerSteve ya itu getParentFragment, tapi bukan itu yang saya maksud Bung, lihat developer.android.com/guide/topics/manifest/…
fikr4n
129

Filosofi saya adalah ini:

Buat aktivitas hanya jika benar-benar diperlukan. Dengan tumpukan belakang tersedia untuk melakukan banyak transaksi fragmen, saya mencoba membuat sesedikit mungkin aktivitas di aplikasi saya. Juga, berkomunikasi antara berbagai fragmen jauh lebih mudah daripada mengirim data bolak-balik antara aktivitas.

Transisi aktivitas itu mahal, bukan? Setidaknya saya percaya begitu - karena aktivitas lama harus dihancurkan / dihentikan / dihentikan, didorong ke stack, dan kemudian aktivitas baru harus dibuat / dimulai / dilanjutkan.

Itu hanya filosofi saya sejak fragmen diperkenalkan.

VJ Vélan Solutions
sumber
2
benar, tetapi seperti yang telah Anda tulis, terkadang diperlukan untuk menggunakan aktivitas. salah satu contohnya adalah layar kamera, di mana lebih baik menggunakannya dalam mode lansekap. contoh lain adalah layar konfigurasi yang ditampilkan saat Anda meletakkan appWidget yang disesuaikan (di "desktop" - aplikasi peluncur).
pengembang android
Terima kasih atas jawaban dan berbagi pengalaman Anda. Jadi menurut Anda ini adalah praktik yang baik di android untuk membatasi aplikasi pada satu Aktivitas dan menggunakan Fragmen untuk semua layar jika arsitektur aplikasi mengizinkannya?
Emil Adz
1
Lalu bagaimana Anda memecahkan masalah fragmen yang harus dilalui satu sama lain "negara"? Semua keadaan di semua fragmen Anda harus hidup dalam satu aktivitas, jika tidak Anda terpaksa menggunakan singleton.
Mr_E
36
Saya tidak yakin bahwa berkomunikasi antara berbagai fragmen jauh lebih mudah daripada mengirim data bolak-balik antara aktivitas.
Denny
3
Setidaknya, onActivityResult()lebih aman dan easer daripada callback fragmen.
CoolMind
59

Nah, menurut kuliah Google (mungkin di sini , saya tidak ingat), Anda harus mempertimbangkan menggunakan Fragmen kapan pun memungkinkan, karena itu membuat kode Anda lebih mudah untuk dipelihara dan dikendalikan.

Namun, saya berpikir bahwa pada beberapa kasus itu bisa menjadi terlalu kompleks, karena aktivitas yang menampung fragmen perlu dinavigasi / berkomunikasi di antara mereka.

Saya pikir Anda harus memutuskan sendiri apa yang terbaik untuk Anda. Biasanya tidak sulit untuk mengubah suatu aktivitas menjadi sebuah fragmen dan sebaliknya.

Saya telah membuat posting tentang dillema ini di sini , jika Anda ingin membaca lebih lanjut.

pengembang android
sumber
5
Terima kasih atas jawaban dan berbagi pengalaman Anda. Jadi menurut Anda ini adalah praktik yang baik di android untuk membatasi aplikasi pada satu Aktivitas dan menggunakan Fragmen untuk semua layar jika arsitektur aplikasi mengizinkannya?
Emil Adz
Tergantung pada proyeknya, tetapi jika terlalu rumit untuk Anda, Anda dapat berpisah dengan beberapa kegiatan juga. Jangan takut untuk menggunakan metode apa pun. Anda juga bisa menggunakan keduanya. Mungkin kadang-kadang akan terlalu sulit bagi Anda untuk menggunakan fragmen alih-alih aktivitas. Saya pikir Anda harus mencoba menggunakan fragmen, tapi jangan memaksanya berada di mana-mana jika terlalu banyak menghalangi Anda ...
Pengembang android
bagaimana jika saya ingin menjaga pengaruh ActionBar ini tetap utuh dan semua konten sedang diaktifkan? Apakah mungkin untuk mencapai ini dengan Aktivitas?
Emil Adz
27

Mengapa saya lebih suka Fragmen daripada Aktivitas di SEMUA KASUS.

  • Aktivitas itu mahal. Dalam Fragmen, tampilan dan status properti dipisahkan - setiap kali fragmen berada backstack, tampilan akan dihancurkan. Jadi, Anda dapat menumpuk lebih banyak Fragmen daripada Aktivitas.

  • Backstackmanipulasi. Dengan FragmentManager, mudah untuk menghapus semua Fragmen, menyisipkan lebih dari pada Fragmen dan dll. Tapi untuk Aktivitas, akan menjadi mimpi buruk untuk memanipulasi hal-hal itu.

  • Siklus hidup yang jauh dapat diprediksi . Selama Aktivitas tuan rumah tidak didaur ulang. Fragmen di backstack tidak akan didaur ulang. Jadi dimungkinkan untuk digunakan FragmentManager::getFragments()untuk menemukan Fragmen spesifik (tidak dianjurkan).

Qylin
sumber
Hai, saya membaca ulasan Anda tentang kelebihan Frag daripada Act, Apakah Anda punya proyek untuk menunjukkan hal yang sama di Github Repo Anda?
Ümañg ßürmån
24

Sejak Jetpack , aplikasi Single-Activity adalah arsitektur yang disukai. Berguna terutama dengan Komponen Arsitektur Navigasi .

sumber

Francis
sumber
Terima kasih untuk ini!
Simão Garcia
1
Saya membaca tentang Jetpack untuk pertama kalinya hari ini. :) Kami membuat aplikasi aktivitas tunggal sejak fragmen diperkenalkan. Kegiatan multi jauh lebih rumit.
luar biasa
1
@TheincredibleJan Anda benar, arsitektur Aplikasi Single Activity adalah solusi yang lebih baik jauh sebelum Jetpack
Francis
12

Menurut saya itu tidak terlalu relevan. Faktor kunci untuk dipertimbangkan adalah

  1. seberapa sering Anda akan menggunakan kembali bagian UI (menu misalnya),
  2. apakah aplikasinya juga untuk tablet?

Penggunaan utama fragmen adalah untuk membangun aktivitas multipane, yang membuatnya sempurna untuk aplikasi responsif Tablet / Telepon.

Isaac Urbina
sumber
Saya akan mengatakan bahwa penggunaan utama fragmen adalah membuat tampilan khusus tanpa menganggapnya sebagai tampilan khusus. itu yang terjadi. Fragmen yang awalnya kami perlihatkan dari Google sebagai cara praktis untuk membuat aplikasi responsif tablet, sehingga Anda dapat menempelkannya di aktivitas yang berbeda jika diinginkan. cara untuk melampirkan kode ke tampilan, lebih atau kurang, dan membuatnya dapat ditempel di tempat yang Anda inginkan (tanpa membuat tampilan khusus).
Lassi Kinnunen
11

Jangan lupa bahwa suatu kegiatan adalah blok / komponen aplikasi yang dapat dibagikan dan dimulai melalui Intent! Jadi setiap aktivitas dalam aplikasi Anda harus menyelesaikan hanya satu jenis tugas. Jika Anda hanya memiliki satu tugas dalam aplikasi Anda maka saya pikir Anda hanya perlu satu aktivitas dan banyak fragmen jika diperlukan. Tentu saja Anda dapat menggunakan kembali fragmen dalam kegiatan di masa mendatang yang menyelesaikan tugas lain. Pendekatan ini akan menjadi pemisahan tugas yang jelas dan logis. Dan Anda tidak perlu mempertahankan satu aktivitas dengan parameter filter maksud berbeda untuk set fragmen yang berbeda. Anda mendefinisikan tugas pada tahap desain proses pengembangan berdasarkan persyaratan.

tamu
sumber
Dalam aplikasi kami, satu jenis tugas kegiatan adalah memegang laci navigasi untuk memasukkan fragmen yang berbeda. :) Mengapa saya harus bergulat dengan niat untuk fragmen? Jelas dan logis untuk menyimpan referensi statis ke kelas data "global" untuk data global dan meneruskan beberapa nilai ke metode instance instance dari fragmen.
luar biasa
9

Ada lebih dari ini yang Anda sadari, Anda harus ingat bahwa aktivitas yang diluncurkan tidak secara implisit menghancurkan aktivitas panggilan. Tentu, Anda dapat mengaturnya sehingga pengguna mengklik tombol untuk pergi ke halaman, Anda memulai aktivitas halaman itu dan menghancurkan yang sekarang. Ini menyebabkan banyak overhead. Panduan terbaik yang bisa saya berikan adalah:

** Mulai aktivitas baru hanya jika masuk akal untuk memiliki aktivitas utama dan yang ini terbuka pada saat yang sama (pikirkan beberapa jendela).

Contoh yang bagus tentang kapan masuk akal untuk melakukan banyak aktivitas adalah Google Drive. Aktivitas utama menyediakan penjelajah file. Ketika file dibuka, aktivitas baru diluncurkan untuk melihat file itu. Anda dapat menekan tombol aplikasi terbaru yang akan memungkinkan Anda untuk kembali ke browser tanpa menutup dokumen yang dibuka, lalu bahkan mungkin membuka dokumen lain secara paralel dengan yang pertama.

TheHebrewHammer
sumber
Re "Mulai aktivitas baru hanya jika masuk akal untuk memiliki aktivitas utama dan yang ini terbuka secara bersamaan (pikirkan beberapa jendela)." Saya kira tidak. Situasi itu diselesaikan dengan baik menggunakan fragmen attach / detachmetode.
ToolmakerSteve
7

Hal yang saya lakukan: Menggunakan lebih sedikit fragmen jika memungkinkan. Sayangnya, hampir bisa dipastikan. Jadi, saya berakhir dengan banyak fragmen dan sedikit kegiatan. Beberapa kekurangan yang saya sadari:

  • ActionBar& Menu: Ketika 2 fragmen memiliki judul, menu yang berbeda, itu
    akan sulit ditangani. Mis: saat menambahkan fragmen baru, Anda bisa mengubah judul bilah tindakan, tetapi saat mengeluarkannyabackstack tidak ada cara untuk mengembalikan judul yang lama. Anda mungkin memerlukan Bilah Alat di setiap fragmen untuk kasus ini, tapi biarkan percaya padaku, itu akan menghabiskan lebih banyak waktu.
  • Ketika kita membutuhkan startForResult, aktivitas memiliki tetapi fragmen belum.
  • Tidak memiliki animasi transisi secara default

Solusi saya untuk ini adalah menggunakan Aktivitas untuk membungkus bagian dalam. Jadi kami memiliki bilah tindakan, menu startActivityForResult,, animasi, ...

Saya Suka Coding
sumber
1
Poin yang sangat berguna, terima kasih. Bisakah Anda mengklarifikasi " Aktivitas untuk membungkus sebuah fragmen "? Apakah Anda membuat Aktivitas terpisah untuk setiap fragmen? Jika demikian, apakah Anda memerlukan Fragmen sama sekali?
ToolmakerSteve
3
ada cara untuk mengembalikan judul dan barang. gunakan getSupportFragmentManager().addOnBackStackChangedListeneruntuk menambah pendengar. dapatkan fragmen saat ini di pendengar itu dan kemudian tetapkan judul dan hal-hal.
babay
4

Salah satu keuntungan besar dari fragmentkegiatan di atas adalah bahwa, kode yang digunakan untuk fragmen dapat digunakan untuk activities.so yang berbeda, memberikan kembali kegunaan dari kode dalam pengembangan aplikasi.

Sanchit Bhasin
sumber
3
Bagaimana? Bisakah Anda memberikan beberapa contoh?
Sof11
1
@ sofs1 Pertanyaan Anda tidak masuk akal. Kode apa pun dalam suatu fragmen tetap sama tidak peduli dari mana aktivitas fragmen tersebut diberlakukan.
luar biasa
@TheincredibleJan Tapi tidak bisakah kita juga mengatakan "Kode apa pun dalam aktivitas tetap sama, tidak peduli dari aktivitas mana aktivitas kedua dipakai."? Saya tidak melihat perbedaannya.
iforce2d
3

menggunakan satu kegiatan per aplikasi untuk menyediakan dasar untuk fragment digunakan fragmentuntuk layar, fragmentsyang berat lite dibandingkan dengan activites fragmen yang dapat digunakan kembali fragmen yang lebih baik cocok untuk aplikasi yang mendukung kedua ponsel & tablet

Varg
sumber
2

Anda bebas menggunakan salah satunya.
Pada dasarnya, Anda harus mengevaluasi mana yang terbaik untuk aplikasi Anda. Pikirkan tentang bagaimana Anda akan mengelola aliran bisnis dan bagaimana menyimpan / mengelola preferensi data.

Pikirkan, bagaimana Fragmen menyimpan data sampah. Saat Anda menerapkan fragmen, Anda memiliki root aktivitas untuk diisi dengan fragmen. Jadi, jika Anda mencoba menerapkan banyak kegiatan dengan terlalu banyak fragmen, Anda harus mempertimbangkan kinerja pada aplikasi Anda, karena Anda memanipulasi (berbicara secara kasar) dua siklus hidup konteks, ingat kompleksitasnya.

Ingat: haruskah saya menggunakan fragmen? Kenapa tidak?

salam.

Franklin Hirata
sumber
1

Saya menggunakan Fragmen untuk pengalaman pengguna yang lebih baik. Misalnya jika Anda memiliki Tombol dan Anda ingin menjalankan katakanlah layanan web ketika Anda mengkliknya, saya melampirkan Fragmen ke Aktivitas induk.

if (id == R.id.forecast) {

    ForecastFragment forecastFragment = new ForecastFragment();
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.main_content, forecastFragment);
    ft.addToBackStack("backstack");
    forecastFragment.setArguments(b);
    ft.commit();
}

Dengan cara itu pengguna tidak harus pindah ke aktivitas lain.

Dan kedua saya lebih suka Fragmen karena Anda dapat menanganinya dengan mudah selama rotasi.

Theo
sumber
Apa yang menjadikan contoh itu pengalaman pengguna yang lebih baik? Bagaimana mereka tahu (atau peduli) bahwa mereka sedang melakukan suatu kegiatan atau sebuah fragmen?
iforce2d
1

Itu tergantung apa yang ingin Anda bangun. Misalnya navigation drawermenggunakan fragmen. Tab juga digunakan fragments. Implementasi lain yang baik, adalah di mana Anda memiliki listview. Ketika Anda memutar telepon dan mengklik satu baris, aktivitas ditampilkan di separuh layar yang tersisa. Secara pribadi, saya menggunakan fragmentsdan fragment dialogs, karena lebih profesional. Plus mereka ditangani lebih mudah dalam rotasi.

Theo
sumber