Bir DialogFragment nasıl doğru bir şekilde reddedilir?


121

Dokümanlar dismiss(), Dialogsınıftaki yöntem için şunu söylüyor :

Bu iletişim kutusunu ekrandan kaldırarak kapatın. Bu yöntem herhangi bir iş parçacığından güvenle çağrılabilir. İletişim kutusu kapatıldığında temizlik yapmak için bu yöntemi geçersiz kılmamanız gerektiğini, bunun yerine bunu uygulamada uygulamanız gerektiğini unutmayın onStop().

Kodumda, tek yaptığım getDialog().dismiss()onu reddetmek için aramak . Ama başka bir şey yapmıyorum, hatta kullanmıyorum onStop(). Bu yüzden DialogFragmentherhangi bir bellek sızıntısını vb. Önlemek için a'yı tam olarak nasıl reddedeceğimi soruyorum .

Yanıtlar:


197

tl; dr: a'yı kapatmanın doğru yolu, doğrudan DialogFragment üzerindeDialogFragment kullanmaktır .dismiss()


Ayrıntılar : DialogFragment durumlarının belgeleri

İletişim kutusunun kontrolü (ne zaman gösterileceğine, gizleneceğine, kapatılacağına karar verme), iletişim kutusundaki doğrudan aramalarla değil, burada API aracılığıyla yapılmalıdır.

Bu nedenle, diyalogda devreyegetDialog().dismiss() gireceği için kullanmamalısınız . Bunun yerine, DialogFragment yöntemini kullanmalısınız :dismiss() dismiss()

public void redd ()

Parçayı ve diyaloğunu kapatın. Parça arka yığına eklendiyse, bu giriş dahil olmak üzere tüm arka yığın durumu açılacaktır. Aksi takdirde, parçayı kaldırmak için yeni bir işlem gerçekleştirilecektir.

Gördüğünüz gibi, bu yalnızca iletişim kutusunu kapatmakla kalmaz, aynı zamanda süreçte yer alan parça işlemlerini de ele alır.

Yalnızca onStopelle temizleme gerektiren herhangi bir kaynağı açıkça oluşturduysanız (dosyaları kapatma, imleçleri kapatma vb.) Kullanmanız gerekir . O zaman bile , temeldeki Dialog onStopyerine DialogFragment'ı geçersiz kılardım onStop.


1
@ScootrNova: Olmamalı, muhtemelen başka bir yerde bir hatanız var. Parçayı nasıl oluşturuyorsunuz?
Heinzi

protected void showDialogFragment(final DialogFragment fragment) {final FragmentTransaction fTransaction = getSupportFragmentManager().beginTransaction(); fTransaction.addToBackStack(null); fragment.show(fTransaction, "dialog");} İğrenç tek astar için üzgünüm! Ama evet haklı olabilirsin, bu yüzden şimdilik DialogFragments'ımı kapatmak için başka bir yol yazdım. Dismiss () yöntemini kullanarak onları reddetme şeklim, sadece parçayı etikete göre bulmak ve boş değilse üzerinde dismiss () çalıştırmaktı. Oh ve evet, newparçayı bu yönteme geçirmeden hemen önce alıyorum .
Charles Madere

2
@ScootrNova: Hmm, bunda yanlış bir şey görmüyorum - diğer yandan uyumluluk kitaplığını hiç kullanmadım, bu yüzden bundan emin olamıyorum. Belki minimal, bağımsız bir örnek oluşturmak ve bununla ilgili yeni bir soru başlatmak mantıklı olabilir.
Heinzi

@CharlesMadere o günlerde bir çözüm buldunuz mu?
JCarlosR

Üzgünüm @JCarlos, bu yıllar önceydi, emin değilim.
Charles Madere

76

A'yı kapatmanın daha iyi bir yolu DialogFragmentşudur:

Fragment prev = getSupportFragmentManager().findFragmentByTag("fragment_dialog");
if (prev != null) {
    DialogFragment df = (DialogFragment) prev;
    df.dismiss();
}

Bu şekilde bir referansa sahip olmak zorunda kalmazsınız DialogFragmentve her yerden kapatabilirsiniz.


7

Neden sadece bu kodu kullanmayı denemiyorsun:

dismiss();

Diyalog Parçasını kendiliğinden yok saymak istiyorsanız. Bu kodu, Diyaloğu kapatmak istediğiniz diyalog parçasının içine koyabilirsiniz.

Örneğin:

button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       dismiss();
   }
});

Bu, ekranda gösterilen son İletişim Parçasını kapatacaktır.

Umarım sana yardımcı olur.


her zaman çalışmıyor
Mahmoud Heretani

5

Terel'in cevabına olumlu oy verdim. Bunu herhangi bir Kotlin kullanıcısı için göndermek istedim:

supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
    (it as DialogFragment).dismiss()
}

Basit kod çok çalışıyor, Güncelleme arkadaşınız için teşekkürler !!
Ayush Katuwal

4

Terel cevabının Kotlin Versiyonu

(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()

1

Seni kovmalısın Dialog, onPause()o yüzden onu geçersiz kıl.

Ayrıca görevden almadan önce kontrol edebilirsiniz nullve aşağıdaki gibi görünmektedir:

@Override
protected void onPause() {
    super.onPause();
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
    }
}

zaten dismiss () yaptığını ve bunun DialogFragment ile ilgili olduğunu yazdı.
Paresh Mayani

Hem Diyalog ve DialogFragments @PareshMayani için bu işleri düşünür
Venky

2
@PareshMayani'nin doğru Venky olduğuna inanıyorum. DialogFragmentGoogle tarafından verilen eğitim, onPause()kullanılan yöntemi hiç göstermiyor . Ama sanırım ne yaptığını anlıyorum. Kullanıcı aramıyorsa ne anlamı var onPause()? Bu, sistemin parçanın çağrıldığını bildiği zamandır. Bir kullanıcının iptal ettiğini söyleyin ne zaman? Bu durumda kapatmanın daha iyi bir yolu nedir?
Andy

1

Diğer cevaplarda resmi belgelere ( DialogFragment Reference ) referanslar var , ancak burada verilen örnekten bahsedilmiyor:

void showDialog() {
    mStackLevel++;

    // DialogFragment.show() will take care of adding the fragment
    // in a transaction.  We also want to remove any currently showing
    // dialog, so make our own transaction and take care of that here.
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    Fragment prev = getFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        ft.remove(prev);
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
    newFragment.show(ft, "dialog");
}

Bu, şu anda gösterilen herhangi bir iletişim kutusunu kaldırır, bir bağımsız değişkenle yeni bir DialogFragment oluşturur ve bunu arka yığında yeni bir durum olarak gösterir. İşlem açıldığında, geçerli DialogFragment ve iletişim kutusu yok edilecek ve önceki (varsa) yeniden gösterilecektir. Bu durumda DialogFragment'ın, iletişim kutusunun açılmasını sağlayacağına dikkat edin, Dialog işlemi ondan ayrı olarak reddedilir.

İhtiyaçlarım için bunu şu şekilde değiştirdim:

FragmentManager manager = getSupportFragmentManager();
Fragment prev = manager.findFragmentByTag(TAG);
if (prev != null) {
    manager.beginTransaction().remove(prev).commit();
}

MyDialogFragment fragment = new MyDialogFragment();
fragment.show(manager, TAG);

1

Diğer yanıtlara eklemek DialogFragment, tam ekran çağrısı olduğunda dismiss(), DialogFragment'ı parça arka yığınından açmaz. Bir geçici çözüm, onBackPressed()ana etkinliği aramaktır.

Bunun gibi bir şey:

CustomDialogFragment.kt

closeButton.onClick {
    requireActivity().onBackPressed()
}

Günü kurtarın, çok teşekkürler
Mahmoud Heretani

0

Reddetmek istediğiniz parçadan dismiss () çağırmanız yeterli.

imageView3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dismiss();
        }
    });

0

<fragment>Parçam gezinme grafiğinde bir etiketle (tam ekran iletişim kutusu için) tanımlandığında, iletişim parçasının dismiss()komutla birlikte kapatılmadığını fark ettim . Bunun yerine, arka yığını patlatmak zorunda kaldım:

findNavController(getActivity(), R.id.nav_host_fragment).popBackStack();

Bununla birlikte, aynı iletişim kutusu, gezinme grafiğinde bir <dialog>etiketle tanımlanmışsa, dismiss()sorunsuz çalışır.


0
CustomFragment dialog = (CustomDataFragment) getSupportFragmentManager().findFragmentByTag("Fragment_TAG");
if (dialog != null) {
  dialog.dismiss();
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.