Apakah ada cara di mana kita dapat menerapkan onBackPressed()
di Android Fragment mirip dengan cara di mana kita menerapkan dalam Aktivitas Android?
Karena siklus hidup Fragmen tidak memiliki onBackPressed()
. Apakah ada metode alternatif lain untuk berkendara onBackPressed()
di fragmen Android 3.0?
android
android-fragments
onbackpressed
Android_programmer_camera
sumber
sumber
Jawaban:
Saya memecahkan dengan cara ini menimpa
onBackPressed
dalam Kegiatan. SemuaFragmentTransaction
adalahaddToBackStack
sebelum komit:sumber
Menurut saya solusi terbaik adalah:
SOLUSI JAWA
Buat antarmuka sederhana:
Dan dalam Aktivitas Anda
Akhirnya di Fragmen Anda:
SOLUSI KOTLIN
1 - Buat Antarmuka
2 - Siapkan Aktivitas Anda
3 - Terapkan dalam Fragmen target Anda
sumber
R.id.main_container
? Apakah itu ID untuk FragmentPager?.?
) dan menegakkan non-nulls (!!
) dapat menyebabkan NPE - para pemain tidak selalu aman. Saya lebih suka menulisif ((fragment as? IOnBackPressed)?.onBackPressed()?.not() == true) { ... }
atau lebih kotliney(fragment as? IOnBackPressed)?.onBackPressed()?.not()?.let { ... }
.onBackPressed()?.takeIf { !it }?.let{...}
?.not()
hanya mengembalikan kebalikannya.val fragment = this.supportFragmentManager.findFragmentById(R.id.flContainer) as? NavHostFragment val currentFragment = fragment?.childFragmentManager?.fragments?.get(0) as? IOnBackPressed currentFragment?.onBackPressed()?.takeIf { !it }?.let{ super.onBackPressed() }
Ini untuk orang yang menggunakan Kotlin dan NavigationControllerMenurut jawaban @HaMMeRed di sini adalah pseudocode bagaimana cara kerjanya. Katakanlah bahwa aktivitas utama Anda disebut
BaseActivity
yang memiliki fragmen anak (seperti dalam contoh SlidingMenu lib). Berikut langkah-langkahnya:Pertama kita perlu membuat antarmuka dan kelas yang mengimplementasikan antarmuka untuk memiliki metode generik
Buat antarmuka kelas
OnBackPressedListener
Buat kelas yang mengimplementasikan keterampilan
OnBackPressedListener
Sejak sekarang, kami akan mengerjakan kode kami
BaseActivity
dan bagian-bagiannyaBuat pendengar pribadi di atas kelas Anda
BaseActivity
buat metode untuk mengatur pendengar
BaseActivity
di override
onBackPressed
mengimplementasikan sesuatu seperti itudalam fragmen
onCreateView
Anda, Anda harus menambahkan pendengar kamiVoila, sekarang ketika Anda mengklik kembali dalam fragmen Anda harus menangkap kebiasaan Anda pada metode kembali.
sumber
onBackPressed()
, fragmen mana yang ditampilkan ketika tombol kembali ditekan?((BaseActivity)activity).setOnBackPressedListener(new OnBackpressedListener(){ public void doBack() { //...your stuff here }});
Ini berfungsi untuk saya: https://stackoverflow.com/a/27145007/3934111
sumber
Jika Anda menginginkan fungsionalitas semacam itu, Anda perlu menimpanya dalam aktivitas Anda, dan kemudian menambahkan
YourBackPressed
antarmuka ke semua fragmen Anda, yang Anda panggil pada fragmen yang relevan setiap kali tombol kembali ditekan.Sunting: Saya ingin menambahkan jawaban saya sebelumnya.
Jika saya melakukan ini hari ini, saya akan menggunakan siaran, atau mungkin siaran yang dipesan jika saya mengharapkan panel lain untuk memperbarui secara bersamaan ke panel konten utama / master.
LocalBroadcastManager
di Perpustakaan Dukungan dapat membantu dengan ini, dan Anda hanya mengirim siaranonBackPressed
dan berlangganan fragmen Anda yang peduli. Saya pikir Messaging adalah implementasi yang lebih terpisah dan akan skala yang lebih baik, jadi itu akan menjadi rekomendasi implementasi resmi saya sekarang. Cukup gunakanIntent
tindakan sebagai filter untuk pesan Anda. kirim yang baru Anda buatACTION_BACK_PRESSED
, kirimkan dari aktivitas Anda dan dengarkan dalam fragmen yang relevan.sumber
LocalBroadcastManager
tidak dapat melakukan siaran yang dipesanTidak ada yang mudah diimplementasikan dan tidak akan berfungsi secara optimal.
Fragmen memiliki pemanggilan metode onDetach yang akan melakukan pekerjaan.
INI AKAN MELAKUKAN PEKERJAAN.
sumber
isRemoving()
seperti yang dijelaskan dalam stackoverflow.com/a/27103891/2914140 .Jika Anda menggunakan
androidx.appcompat:appcompat:1.1.0
atau di atas maka Anda dapat menambahkanOnBackPressedCallback
fragmen Anda sebagai berikutLihat https://developer.android.com/guide/navigation/navigation-custom-back
sumber
androidx-core-ktx
, Anda dapat menggunakanrequireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { /* code to be executed when back is pressed */ }
LifecycleOwner
param harus ditambahkan seperti pada contoh ini. Tanpa itu, setiap fragmen yang dimulai setelahnya akan memanggilhandleBackPressed()
jika tombol kembali ditekan.Cukup tambahkan
addToBackStack
saat Anda beralih antar fragmen Anda seperti di bawah ini:jika Anda menulis
addToBackStack(null)
, ia akan menanganinya sendiri tetapi jika Anda memberi tag, Anda harus menanganinya secara manual.sumber
karena pertanyaan ini dan beberapa jawabannya sudah lebih dari lima tahun, izinkan saya berbagi solusi. Ini adalah tindak lanjut dan modernisasi jawaban dari @oyenigun
UPDATE: Di bagian bawah artikel ini, saya menambahkan implementasi alternatif menggunakan ekstensi Fragmen abstrak yang tidak akan melibatkan Kegiatan sama sekali, yang akan berguna bagi siapa pun dengan hierarki fragmen yang lebih kompleks yang melibatkan fragmen bersarang yang membutuhkan perilaku punggung yang berbeda.
Saya perlu menerapkan ini karena beberapa fragmen yang saya gunakan memiliki tampilan lebih kecil yang ingin saya abaikan dengan tombol kembali, seperti tampilan informasi kecil yang muncul, dll, tetapi ini bagus untuk siapa saja yang perlu menimpa perilaku tombol kembali di dalam fragmen.
Pertama, tentukan Antarmuka
Antarmuka ini, yang saya sebut
Backable
(saya stickler untuk konvensi penamaan), memiliki metode tunggalonBackPressed()
yang harus mengembalikanboolean
nilai. Kita perlu menegakkan nilai boolean karena kita perlu tahu apakah tekan tombol kembali telah "menyerap" acara kembali. Kembalitrue
berarti sudah, dan tidak ada tindakan lebih lanjut diperlukan, jika tidak,false
mengatakan bahwa tindakan kembali standar masih harus dilakukan. Antarmuka ini harus berupa file sendiri (lebih disukai dalam paket terpisah bernamainterfaces
). Ingat, memisahkan kelas Anda ke dalam paket adalah praktik yang baik.Kedua, temukan fragmen atas
Saya membuat metode yang mengembalikan
Fragment
objek terakhir di tumpukan belakang. Saya menggunakan tag ... jika Anda menggunakan ID, buat perubahan yang diperlukan. Saya memiliki metode statis ini di kelas utilitas yang berhubungan dengan status navigasi, dll ... tapi tentu saja, letakkan di tempat yang paling cocok untuk Anda. Untuk perbaikan, saya telah memasukkan milik saya di kelas yang disebutNavUtils
.Pastikan jumlah tumpukan kembali lebih besar dari 0, jika tidak,
ArrayOutOfBoundsException
dapat dilempar saat runtime. Jika tidak lebih besar dari 0, kembalikan nol. Kami akan memeriksa nilai nol nanti ...Ketiga, Implementasikan dalam Fragmen
Menerapkan
Backable
antarmuka di bagian mana pun di mana Anda perlu mengganti perilaku tombol kembali. Tambahkan metode implementasi.Dalam
onBackPressed()
mengganti, masukkan logika apa pun yang Anda butuhkan. Jika Anda ingin tombol kembali tidak memunculkan tumpukan belakang (perilaku default), kembali benar , bahwa acara kembali Anda telah diserap. Jika tidak, kembalikan salah.Terakhir, di Aktivitas Anda ...
Ganti
onBackPressed()
metode dan tambahkan logika ini ke dalamnya:Kami mendapatkan fragmen saat ini di tumpukan belakang, kemudian kami melakukan pemeriksaan nol dan menentukan apakah itu mengimplementasikan
Backable
antarmuka kami . Jika ya, tentukan apakah acara itu diserap. Jika demikian, kita sudah selesaionBackPressed()
dan dapat kembali. Kalau tidak, perlakukan itu sebagai tekan kembali normal dan panggil metode super.Opsi kedua untuk tidak melibatkan Aktivitas
Kadang-kadang, Anda sama sekali tidak ingin Kegiatan menangani ini, dan Anda perlu menanganinya secara langsung di dalam fragmen. Tetapi siapa yang bilang Anda tidak bisa memiliki Fragmen dengan back press API? Cukup rentangkan fragmen Anda ke kelas baru.
Buat kelas abstrak yang memperluas Fragmen dan mengimplementasikan
View.OnKeyListner
antarmuka ...Seperti yang Anda lihat, setiap fragmen yang meluas
BackableFragment
akan secara otomatis menangkap kembali klik menggunakanView.OnKeyListener
antarmuka. Panggil sajaonBackButtonPressed()
metode abstrak dari dalamonKey()
metode yang diimplementasikan menggunakan logika standar untuk membedakan tekan tombol kembali. Jika Anda perlu mendaftarkan klik kunci selain tombol kembali, pastikan untuk memanggilsuper
metode ketika menimpaonKey()
fragmen Anda, jika tidak Anda akan menimpa perilaku di abstraksi.Mudah digunakan, cukup rentangkan dan terapkan:
Karena
onBackButtonPressed()
metode di kelas super abstrak, setelah Anda memperluas Anda harus menerapkanonBackButtonPressed()
. Ini kembalivoid
karena hanya perlu melakukan tindakan dalam kelas fragmen, dan tidak perlu menyampaikan penyerapan pers kembali ke Aktivitas. Pastikan Anda memanggilonBackPressed()
metode Aktivitas jika apa pun yang Anda lakukan dengan tombol kembali tidak memerlukan penanganan, jika tidak, tombol kembali akan dinonaktifkan ... dan Anda tidak menginginkan itu!Peringatan Seperti yang Anda lihat, ini mengatur pendengar kunci ke tampilan root dari fragmen, dan kita harus memfokuskannya. Jika ada teks edit yang terlibat (atau tampilan mencuri fokus lainnya) dalam fragmen Anda yang memperluas kelas ini, (atau fragmen dalam lainnya atau tampilan yang memiliki yang sama), Anda harus mengatasinya secara terpisah. Ada artikel bagus tentang cara memperpanjang EditText untuk kehilangan fokus pada tekanan balik.
Saya harap seseorang menemukan ini berguna. Selamat coding.
sumber
super.onBackPressed();
dua kali?currentFragment
. Jika fragmen tidak nol dan fragmen mengimplementasikanBackable
antarmuka, tidak ada tindakan yang diambil. Jika fragmen tidak nol dan TIDAK diterapkanBackable
, kami memanggil metode super. Jika fragmennya nol, ia melompati panggilan super terakhir.currentFragment
bukan nol dan merupakan turunan dari Backable dan terlepas (kami menekanback
tombol dan menutup fragmen) kemunculan pertamasuper.onBackPressed();
disebut, kemudian yang kedua.Solusinya sederhana:
1) Jika Anda memiliki kelas fragmen dasar yang diperluas oleh semua fragmen, kemudian tambahkan kode ini ke kelasnya, jika tidak, buat kelas fragmen basis seperti itu
2) Di kelas Aktivitas Anda, ganti onBackPressed sebagai berikut:
3) Di kelas Fragmen Anda, tambahkan kode yang Anda inginkan:
sumber
onBackPressed()
menyebabkan Fragmen terlepas dari Aktivitas.Menurut @Sterling Diaz menjawab, saya pikir dia benar. TAPI beberapa situasi akan salah. (mis. Layar Putar)
Jadi, saya pikir kita bisa mendeteksi apakah
isRemoving()
akan mencapai tujuan.Anda dapat menulisnya di
onDetach()
atauonDestroyView()
. Itu bekerja.sumber
Yah saya melakukannya seperti ini, dan itu bekerja untuk saya
Antarmuka yang sederhana
FragmentOnBackClickInterface.java
Contoh implementasi
MyFragment.java
lalu timpa saja diBackPressed dalam aktivitas
sumber
Anda harus menambahkan antarmuka ke proyek Anda seperti di bawah ini;
Dan kemudian, Anda harus mengimplementasikan antarmuka ini pada fragmen Anda;
Dan Anda dapat memicu acara onBackPressed ini di bawah aktivitas Anda di acaraBackPressed seperti di bawah ini;
sumber
getActivity().onBackPressed();
karena akan memanggil pengecualian: "java.lang.StackOverflowError: ukuran stack 8MB".Ini hanya kode kecil yang akan melakukan trik:
Semoga ini bisa membantu seseorang :)
sumber
Jika Anda menggunakan EventBus, itu mungkin solusi yang jauh lebih sederhana:
dan di kelas Aktivitas Anda, Anda dapat mendefinisikan:
BackPressedMessage.java hanyalah objek POJO
Ini sangat bersih dan tidak ada kerumitan antarmuka / implementasi.
sumber
ini solusi saya:
sumber
Menggunakan komponen Navigasi, Anda dapat melakukannya seperti ini :
sumber
Bagaimana dengan menggunakan onDestroyView ()?
sumber
i = i
atauif (1 < 0) {}
.sumber
dalam fragmen Anda tambahkan berikut ini, jangan lupa untuk mengimplementasikan antarmuka mainaktivitas.
sumber
Dalam solusi saya (Kotlin);
Saya menggunakan fungsi onBackAlternative sebagai parameter pada BaseActivity .
BaseActivity
Saya memiliki fungsi untuk mengatur onBackPressAlternative di BaseFragment .
BaseFragment
Kemudian onBackPressAlternative saya siap digunakan pada fragmen.
Sub Fragmen
sumber
Jangan menerapkan metode ft.addToBackStack () sehingga ketika Anda menekan tombol kembali aktivitas Anda akan selesai.
sumber
Ikuti saja langkah-langkah ini:
Selalu sambil menambahkan fragmen,
Kemudian di aktivitas utama, timpa
onBackPressed()
Untuk menangani tombol kembali di aplikasi Anda,
Itu dia!
sumber
Dalam siklus hidup aktivitas, selalu tombol android kembali berurusan dengan transaksi FragmentManager ketika kami menggunakan FragmentActivity atau AppCompatActivity.
Untuk menangani backstack, kita tidak perlu menangani count backstack atau menandai apa pun, tetapi kita harus tetap fokus sambil menambahkan atau mengganti sebuah fragmen. Silakan temukan cuplikan berikut untuk menangani case tombol kembali,
Di sini, saya tidak akan menambahkan tumpukan kembali untuk fragmen rumah saya karena itu adalah halaman rumah aplikasi saya. Jika menambahkan addToBackStack ke HomeFragment maka aplikasi akan menunggu untuk menghapus semua framen dalam kegiatan maka kita akan mendapatkan layar kosong jadi saya menjaga kondisi berikut,
Sekarang, Anda dapat melihat fragmen yang ditambahkan sebelumnya pada aktivitas dan aplikasi akan keluar ketika mencapai HomeFragment. Anda juga dapat melihat cuplikan berikut.
sumber
Fragmen: Buat metode BaseFragment menempatkan:
Aktivitas:
Aktivitas Anda akan berjalan di atas fragmen yang terlampir dan terlihat dan memanggilBackPressed () pada masing-masing dari mereka dan membatalkan jika salah satu dari mereka mengembalikan 'benar' (artinya telah ditangani, jadi tidak ada tindakan lebih lanjut).
sumber
Menurut catatan rilis AndroidX ,
androidx.activity 1.0.0-alpha01
dirilis dan memperkenalkanComponentActivity
, kelas dasar baru yang adaFragmentActivity
danAppCompatActivity
. Dan rilis ini memberi kita fitur baru:Anda sekarang dapat mendaftarkan
OnBackPressedCallback
viaaddOnBackPressedCallback
untuk menerimaonBackPressed()
panggilan balik tanpa perlu mengganti metode dalam aktivitas Anda.sumber
Anda dapat mendaftarkan fragmen dalam aktivitas untuk menangani kembali pers:
pemakaian:
Dalam Fragmen:
Dalam Aktivitas:
sumber
Menyediakan navigasi belakang khusus dengan menangani diBackPressed sekarang lebih mudah dengan panggilan balik di dalam fragmen.
Jika Anda ingin tindakan kembali default berdasarkan beberapa kondisi, Anda dapat menggunakan:
sumber
Di dalam metode onCreate fragmen tambahkan yang berikut:
sumber
Solusi terbaik,
sumber