डायलॉगफ्रैगमेंट को सही तरीके से कैसे खारिज करें?


121

डॉक्स वर्ग dismiss()से विधि के लिए यह कहते हैं Dialog:

स्क्रीन से हटाते हुए, इस संवाद को खारिज करें। यह विधि किसी भी धागे से सुरक्षित रूप से मंगाई जा सकती है। ध्यान दें कि संवाद को खारिज करने पर आपको सफाई करने के लिए इस पद्धति को ओवरराइड नहीं करना चाहिए, इसके बजाय इसे लागू करें onStop()

मेरे कोड में, मैं getDialog().dismiss()इसे खारिज करने के लिए कॉल करता हूं । लेकिन मैं कुछ और भी कर रहा हूं या उपयोग नहीं कर रहा हूं onStop()। इसलिए मैं ठीक से पूछ रहा हूं कि DialogFragmentकिसी भी मेमोरी लीक आदि से बचने के लिए सही तरीके से कैसे खारिज किया जाए।

जवाबों:


197

tl; dr: डायलॉगफ्रैगमेंट पर सीधेDialogFragment उपयोग करने के लिए एक को बंद करने का सही तरीका है ।dismiss()


विवरण : DialogFragment राज्यों के प्रलेखन

डायलॉग का नियंत्रण (यह दिखाने के लिए कि कब दिखाना, छिपाना, उसे खारिज करना) एपीआई के माध्यम से किया जाना चाहिए, संवाद पर सीधे कॉल के साथ नहीं।

इस प्रकार, आपको उपयोग नहीं करना चाहिए getDialog().dismiss(), क्योंकि यह dismiss() संवाद पर लागू होगा । इसके बजाय, आपको dismiss()स्वयं DialogFragment की विधि का उपयोग करना चाहिए :

सार्वजनिक शून्य खारिज ()

खंडन और उसके संवाद को खारिज करें। यदि टुकड़ा बैक स्टैक में जोड़ा गया था, तो इस प्रविष्टि में सभी बैक स्टैक स्थिति में शामिल होंगे और इसमें शामिल होंगे। अन्यथा, टुकड़े को निकालने के लिए एक नया लेनदेन करने के लिए प्रतिबद्ध होगा।

जैसा कि आप देख सकते हैं, यह न केवल संवाद को बंद करने का ध्यान रखता है, बल्कि इस प्रक्रिया में शामिल खंड लेनदेन को भी संभालता है।

आपको केवल उपयोग करने की आवश्यकता है onStopयदि आपने स्पष्ट रूप से किसी भी संसाधन का निर्माण किया है जिसके लिए मैनुअल क्लीनअप (फाइलें बंद करना, शाप देना आदि) की आवश्यकता होती है। फिर भी, मैं अंतर्निहित डायलॉग के onStopबजाय डायलॉगफ्रैगमेंट को ओवरराइड करूंगा onStop


1
@ScootrNova: ऐसा नहीं होना चाहिए, आपके पास शायद एक बग है। आप टुकड़ा कैसे बना रहे हैं?
हिनजी

protected void showDialogFragment(final DialogFragment fragment) {final FragmentTransaction fTransaction = getSupportFragmentManager().beginTransaction(); fTransaction.addToBackStack(null); fragment.show(fTransaction, "dialog");} बुरा एक लाइनर के लिए क्षमा करें! लेकिन हाँ, आप सही हो सकते हैं, इसलिए समय के लिए मैंने अपने DialogFragments को बंद करने का एक और तरीका लिखा है। जिस तरह से मैं बर्खास्तगी () विधि का उपयोग करके उन्हें खारिज कर रहा था वह केवल टैग द्वारा टुकड़ा ढूंढ रहा था और फिर इसे खारिज कर रहा था (अगर यह शून्य नहीं था)। ओह और हाँ, मैं newउस विधि को पारित करने से पहले टुकड़े को ठीक कर रहा हूं ।
चार्ल्स मैडरे

2
@ScootrNova: हम्म, इसके साथ कुछ भी गलत न देखें - दूसरी ओर, मैंने कभी भी कम्पैटिबिलिटी लाइब्रेरी का इस्तेमाल नहीं किया है, इसलिए मैं इस बारे में निश्चित नहीं हो सकता। हो सकता है कि यह एक न्यूनतम, आत्म-निहित उदाहरण बनाने और उस पर एक नया प्रश्न शुरू करने के लिए समझ में आता हो।
हेनजी

@CharlesMadere उन दिनों में, क्या आपको कोई समाधान मिला?
JCarlosR

क्षमा करें @Jarlos, यह साल पहले था, मैं अनिश्चित हूँ।
चार्ल्स मैडरे

76

मुझे लगता है कि DialogFragmentयह बंद करने का एक बेहतर तरीका है:

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

इस तरह से आपको न तो कोई संदर्भ देना होगा DialogFragmentऔर न ही इसे हर जगह से बंद किया जा सकता है।


7

आप केवल इस कोड का उपयोग करने का प्रयास क्यों नहीं करते हैं:

dismiss();

अगर आप अपने हिसाब से Dialog Fragment को खारिज करना चाहते हैं। आप इस कोड को संवाद खंड के अंदर रख सकते हैं जहां आप संवाद को खारिज करना चाहते हैं।

उदाहरण के लिए:

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

यह स्क्रीन पर दिखाए गए हाल के डायलॉग फ्रैगमेंट को बंद कर देगा।

आशा है कि यह आपके लिए मदद करता है।


हर समय काम नहीं
महमूद हेठानी

5

मैंने टेरेल के जवाब पर नाराजगी जताई। मैं किसी भी कोटलिन उपयोगकर्ताओं के लिए यह पोस्ट करना चाहता था:

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

सरल कोड कड़ी मेहनत करता है, अद्यतन दोस्त के लिए धन्यवाद !!
आयुष कटुवाल

4

Terel उत्तर का कोटलिन संस्करण

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

1

आप आप को खारिज करना चाहिए Dialogमें onPause()तो यह ओवरराइड।

खारिज करने से पहले आप nullस्निपेट के लिए नीचे की तरह दिखा सकते हैं और दिखा रहे हैं:

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

उन्होंने पहले ही लिखा है कि वह डायलॉगफ्रेग्मेंट के बारे में खारिज () और इसके बारे में कर रहे हैं।
परेश मयानी

मुझे लगता है कि यह संवाद और संवाद दोनों के लिए काम करता है @PareshMayani
Venky

2
मेरा मानना ​​है कि @PareshMayani वेंकी सही है। DialogFragmentGoogle द्वारा ट्यूटोरियल में onPause()उपयोग की जाने वाली विधि बिल्कुल नहीं दिखाई देती है । लेकिन मुझे लगता है कि मैं देख रहा हूं कि आप क्या कर रहे हैं। यदि उपयोगकर्ता कॉल नहीं कर रहा है, तो इस बिंदु को व्हाट्सएप करें onPause()। जब सिस्टम जानता है कि टुकड़े को दूर कहा जा रहा है। जब कोई उपयोगकर्ता रद्द करता है, तो उसके बारे में क्या कहेंगे। उस मामले में इसे बंद करने का एक बेहतर तरीका है?
एंडी

1

अन्य उत्तरों में आधिकारिक डॉक्स ( DialogFragment Reference ) के संदर्भ हैं , लेकिन वहां दिए गए उदाहरण का कोई उल्लेख नहीं है:

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");
}

यह वर्तमान में दिखाए गए किसी भी डायलॉग को हटा देता है, एक तर्क के साथ एक नया डायलॉगफ्रेगमेंट बनाता है, और इसे बैक स्टैक पर एक नए राज्य के रूप में दिखाता है। जब लेनदेन पॉप हो जाता है, तो वर्तमान डायलॉगग्रैगमेंट और उसका डायलॉग नष्ट हो जाएगा, और पिछले एक (यदि कोई है) को फिर से दिखाया गया है। ध्यान दें कि इस मामले में DialogFragment डायलॉग के लेन-देन को रोकने का ध्यान रखेगा और इसे अलग से खारिज कर दिया जाएगा।

अपनी जरूरतों के लिए मैंने इसे इसमें बदल दिया:

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

जब DialogFragmentपूर्ण स्क्रीन कॉलिंग होती है तो अन्य उत्तरों को जोड़ना, dismiss()खंड बैकस्ट से DialogFragment को पॉप नहीं करेगा। onBackPressed()मूल गतिविधि पर कॉल करने के लिए एक समाधान है ।

कुछ इस तरह:

CustomDialogFragment.kt

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

दिन बचाओ, बहुत बहुत धन्यवाद
महमूद हेरेटानी

0

जिस खंड को आप खारिज करना चाहते हैं, बस बर्खास्तगी () को कॉल करें।

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

0

मैंने पाया कि जब मेरे टुकड़े को नेविगेशन ग्राफ में एक <fragment>टैग (पूर्ण स्क्रीन डायलॉगफ्रैगमेंट के लिए) के साथ परिभाषित किया गया था , तो डायलफ्रैगमेंट dismiss()कमांड के साथ खारिज नहीं होगा । इसके बजाय, मुझे बैक स्टैक पॉप करना पड़ा:

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

हालाँकि, यदि एक ही डायलॉगैगमेंट को नेविगेशन ग्राफ में एक <dialog>टैग के साथ परिभाषित किया गया था, तो dismiss()ठीक काम करता है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.