Bu soru ve bazı cevaplar beş yaşın üzerinde olduğundan çözümümü paylaşmama izin verin. Bu @oyenigun'un cevabı için bir takip ve modernizasyon
GÜNCELLEME:
Bu makalenin en altına, Etkinliği hiç içermeyen soyut bir Fragment uzantısı kullanarak alternatif bir uygulama ekledim.
Bunu kullanmam gerekiyordu, çünkü kullandığım bazı parçaların, geri açılan küçük bilgi görünümleri gibi geri düğmesiyle kapatmak istediğim daha küçük görünümleri var, ancak bu, davranışını geçersiz kılması gereken herkes için iyi parçaların içindeki geri düğmesi.
İlk olarak, bir Arayüz tanımlayın
public interface Backable {
boolean onBackPressed();
}
Aradığım bu arabirimin Backable
(adlandırma kuralları için bir stickler olduğum), onBackPressed()
bir boolean
değer döndürmesi gereken tek bir yöntemi var . Bir boolean değeri uygulamamız gerekir, çünkü geri düğmesine basmanın geri olayı "absorbe edip etmediğini" bilmemiz gerekir. Geri dönmek true
, bunun olduğu ve başka bir işlem yapılması gerekmediği anlamına gelir, aksi takdirde, false
varsayılan geri işlemin yine de yapılması gerektiğini söyler. Bu arayüz kendi dosyası olmalıdır (tercihen ayrı bir pakette interfaces
). Unutmayın, sınıflarınızı paketlere ayırmak iyi bir uygulamadır.
İkincisi, üst parçayı bulun
Fragment
Arka yığındaki son nesneyi döndüren bir yöntem oluşturdum . Etiketleri kullanıyorum ... kimlikler kullanıyorsanız, gerekli değişiklikleri yapın. Navigasyon durumları, vb ile ilgilenen bir yardımcı program sınıfında bu statik yöntem var ... ama tabii ki, size en uygun yere koy. Eğitim için, benimkini adlı bir sınıfa koydum NavUtils
.
public static Fragment getCurrentFragment(Activity activity) {
FragmentManager fragmentManager = activity.getFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0) {
String lastFragmentName = fragmentManager.getBackStackEntryAt(
fragmentManager.getBackStackEntryCount() - 1).getName();
return fragmentManager.findFragmentByTag(lastFragmentName);
}
return null;
}
Arka yığın sayısının 0'dan büyük olduğundan emin olun, aksi takdirde ArrayOutOfBoundsException
çalışma zamanında bir fırlatma yapılabilir. 0'dan büyük değilse null değerini döndürün. Daha sonra boş bir değer olup olmadığını kontrol edeceğiz ...
Üçüncüsü, Bir Parçada Uygulama
Uygulamak Backable
geri düğmesi davranışı geçersiz gereken yere hangisi parçası içinde arayüz. Uygulama yöntemini ekleyin.
public class SomeFragment extends Fragment implements
FragmentManager.OnBackStackChangedListener, Backable {
...
@Override
public boolean onBackPressed() {
// Logic here...
if (backButtonShouldNotGoBack) {
whateverMethodYouNeed();
return true;
}
return false;
}
}
In onBackPressed()
geçersiz kılma, nasıl istersen mantık koydu. Geri düğmesi istiyorsanız değil arka yığını (varsayılan davranış) pop, dönmek gerçek sırt olay absorbe edildiğini,. Aksi takdirde, false değerini döndürün.
Son olarak, Faaliyetinizde ...
onBackPressed()
Yöntemi geçersiz kılın ve bu mantığı buna ekleyin:
@Override
public void onBackPressed() {
// Get the current fragment using the method from the second step above...
Fragment currentFragment = NavUtils.getCurrentFragment(this);
// Determine whether or not this fragment implements Backable
// Do a null check just to be safe
if (currentFragment != null && currentFragment instanceof Backable) {
if (((Backable) currentFragment).onBackPressed()) {
// If the onBackPressed override in your fragment
// did absorb the back event (returned true), return
return;
} else {
// Otherwise, call the super method for the default behavior
super.onBackPressed();
}
}
// Any other logic needed...
// call super method to be sure the back button does its thing...
super.onBackPressed();
}
Mevcut parçayı arka yığın halinde alıyoruz, sonra boş bir kontrol yapıyoruz ve Backable
arayüzümüzü uygulayıp uygulamadığını tespit ediyoruz . Varsa, olayın emilip emilmediğini belirleyin. Eğer öyleyse, işimiz bitti onBackPressed()
ve geri dönebiliriz. Aksi takdirde, normal bir geri basma gibi davranın ve süper yöntemi çağırın.
Etkinliği Dahil Etmemek İçin İkinci Seçenek
Bazen, Aktivitenin bunu hiç ele almasını istemezsiniz ve doğrudan parça içinde ele almanız gerekir. Peki geri bastırma API'sı olan Fragmanlara sahip olamayacağınızı kim söylüyor ? Parçanızı yeni bir sınıfa genişletmeniz yeterlidir.
Fragment'ı genişleten ve View.OnKeyListner
arabirimi uygulayan soyut bir sınıf oluşturun ...
import android.app.Fragment;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
public abstract class BackableFragment extends Fragment implements View.OnKeyListener {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(this);
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackButtonPressed();
return true;
}
}
return false;
}
public abstract void onBackButtonPressed();
}
Gördüğünüz gibi, uzayan herhangi bir parça arayüzü BackableFragment
kullanarak otomatik olarak geri tıklamaları yakalayacaktır View.OnKeyListener
. Sadece bir geri düğmesine basın ayırt etmek için standart mantık kullanarak onBackButtonPressed()
uygulanan onKey()
yöntem içinde soyut yöntemi çağırmak . Geri düğmesi dışındaki tuş tıklamalarını kaydetmeniz gerekiyorsa super
, parçanızda geçersiz kılınırken yöntemi çağırdığınızdan emin olun onKey()
, aksi takdirde soyutlamadaki davranışı geçersiz kılarsınız.
Kullanımı basit, sadece genişletip uygulayın:
public class FragmentChannels extends BackableFragment {
...
@Override
public void onBackButtonPressed() {
if (doTheThingRequiringBackButtonOverride) {
// do the thing
} else {
getActivity().onBackPressed();
}
}
...
}
Yana onBackButtonPressed()
süper sınıfındaki yöntem soyut, sen uzatmak kez uygulamalıdır onBackButtonPressed()
. Geri dönüyor, void
çünkü sadece parça sınıfı içinde bir eylem gerçekleştirmesi gerekiyor ve basının emilimini tekrar Faaliyete aktarması gerekmiyor. Geri düğmesi ile ne yaparsanız yapın işlem gerektirmiyorsa , Etkinlik yöntemini çağırdığınızdan emin olunonBackPressed()
, aksi takdirde geri düğmesi devre dışı bırakılır ... ve bunu istemezsiniz!
Uyarılar
Gördüğünüz gibi, bu anahtar dinleyiciyi parçanın kök görünümüne ayarlar ve odaklamamız gerekir. Parçanızda bu sınıfı genişleten (veya aynı iç kısımlara veya aynı görünümlere sahip) düzenleme metinleri (veya başka bir odak çalma görünümü) varsa, bunu ayrı olarak ele almanız gerekir. Arka baskıya odaklanmamak için bir EditText'i genişletmeyle ilgili iyi bir makale var .
Umarım birisi bunu faydalı bulur. Mutlu kodlama.