टुकड़ों का उपयोग करके वापस स्टैक साफ़ करें


244

मैंने अपने एंड्रॉइड ऐप को हनीकॉम्ब में पोर्ट किया और टुकड़ों का उपयोग करने के लिए मैंने एक बड़ा रिफ्लेक्टर किया। अपने पिछले संस्करण में, जब मैंने होम बटन दबाया था तो मैं ACTIVITY_CLEAR_TOPबैक स्टैक को रीसेट करने के लिए एक का उपयोग करता था ।

अब मेरा ऐप कई टुकड़ों के साथ सिर्फ एक गतिविधि है, इसलिए जब मैं होम बटन दबाता हूं तो मैं इसके अंदर के टुकड़े को बदल देता हूं। झंडे के startActivityसाथ उपयोग किए बिना मैं अपनी पीठ को कैसे साफ कर सकता हूं ACTIVITY_CLEAR_TOP?


वापस ढेर का उपयोग करने से बचें! यह वास्तव में समग्र दक्षता के साथ मदद नहीं करता है! हर बार जब आप नेविगेट करना चाहते हैं तो प्लेन रिप्लेसमेंट () या इससे भी बेहतर रिमूव / ऐड का उपयोग करें! पर मेरी पोस्ट की जाँच करें stackoverflow.com/questions/5802141/...
stack_ved

जवाबों:


430

मैंने यहां कुछ ऐसा ही पोस्ट किया है

जोआनिम के जवाब से, डायने हैकॉर्न से:

http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42

मैं बस का उपयोग कर समाप्त हुआ:

FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {    
    fm.popBackStack();
}

लेकिन समान रूप से कुछ का उपयोग कर सकते हैं:

((AppCompatActivity)getContext()).getSupportFragmentManager().popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)

जो सभी राज्यों को नामित नाम तक देगा। फिर आप केवल उस टुकड़े को बदल सकते हैं जो आप चाहते हैं


8
खैर, यह एक या अधिक बार बैक बटन मारने के बराबर है, इसलिए यह वर्तमान में दिखाई देने वाले टुकड़े को बदल देता है। (कम से कम जब मैंने इसकी कोशिश की है)
पीटर अज़ताई

7
मैं याचिकाकर्ता के रूप में एक ही मुद्दा रहा हूँ। मैं उन सभी अंशों को हटा देना चाहता हूं जिनके बजाय यह चक्र है जिसके बहुत सारे निहितार्थ हैं। उदाहरण के लिए, आप जीवनचक्र की घटनाओं से टकराएंगे, जिन्हें आपको स्टैक के हर टुकड़े को क्रमिक रूप से पॉपिंग करने की आवश्यकता नहीं है।
ब्रायन ग्रिफ़े

233
शीर्ष पर जाने के लिए बस उपयोग करें: fragmentManager.popBackStack (null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
तानापिट

53
यह किस लिए लायक है, इसके लिए विखंडन का उपयोग कर रहा है। popBackStackImmediate (null, FragmentManager.POP_BACK_STACK_INCLUSIVE); मेरे लिए और भी बेहतर काम किया क्योंकि इसने टुकड़े के एनिमेशन को क्रियान्वित करने से रोक दिया था
रोस्टर

17
यह ठीक से काम नहीं करता है - यह बीच में हर टुकड़े के onStart पर एक कॉल ट्रिगर करेगा
जेम्स

165

@ Warpzit की टिप्पणी के लिए एक उत्तर बनाने के लिए और दूसरों के लिए इसे ढूंढना आसान बनाएं।

उपयोग:

fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

14
मेरा मानना ​​है कि AppCompatActivity का उपयोग करते समय नवीनतम v7-appCompat लाइब्रेरी में इस तरह बैकस्टैक से सभी टुकड़ों को पॉपिंग करना टूट गया है। मेरे ऐप को नवीनतम v7-appCompat लाइब्रेरी (21.0.0) में अपडेट करने और नए AppCompatActivity को विस्तारित करने के बाद, उपरोक्त तरीके से टुकड़े टुकड़े करने से फ्रैगमेंट मैनेजर के बैकस्टैक रिकॉर्ड में कुछ टुकड़े निकल रहे हैं। मैं इसके इस्तेमाल के खिलाफ सलाह दूंगा।
dell116

हो सकता है popBackStackImmediate का उपयोग करें।
कन्नन_सजद २

38

सभी शामिल पक्षों के लिए उचित सम्मान के साथ; मैं यह देखकर बहुत हैरान हूं कि आप में से कितने लोग एक साधारण से पूरे टुकड़े को वापस ढेर कर सकते हैं

fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

Android प्रलेखन के अनुसार ( nameतर्क के बारे में - दावा किए गए कार्य प्रस्तावों में "अशक्त")।

यदि अशक्त, केवल शीर्ष स्थिति पॉप है

अब, मुझे एहसास हुआ कि मुझे आपके विशेष कार्यान्वयनों का ज्ञान नहीं है (जैसे कि समय में दिए गए स्टैक में आपकी कितनी प्रविष्टियाँ हैं), लेकिन मैं अपने सभी पैसे स्वीकार किए गए उत्तर पर शर्त लगाऊंगा जब एक अच्छी तरह से परिभाषित होने की उम्मीद है उपकरणों और विक्रेताओं की एक विस्तृत श्रृंखला पर व्यवहार:

(संदर्भ के लिए, इसके साथ कुछ)

FragmentManager fm = getFragmentManager(); // or 'getSupportFragmentManager();'
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {    
    fm.popBackStack();
}

4
मेरे लिए यह नहीं था क्योंकि प्रत्येक पॉप आपको आंतरिक रूप से प्रत्येक टुकड़े के onCreateView पर ले जाता है। जहां मुझे कुछ संसाधन पर एनपीई प्राप्त होगा। लेकिन fm.popBackStack (null, FragmentManager.POP_BACK_STACK_INCLUSA) का उपयोग कर ; बस सभी बैकस्टैक मारे गए।
सूद।

1
लूप का उपयोग करके पॉपिंग करते समय onCreateView कॉल कैसे छोड़ें इस पर कोई जानकारी?
आयुष गोयल

सबसे ऊपर के टुकड़े (नल) को साफ करने से पीछे के ढेर में आने वाले सभी टुकड़े साफ हो जाएंगे।
2b77bee6-5445-4c77-b1eb-4df3e5

18

लूप का उपयोग किए बिना मेरे और आसान तरीके के लिए काम करता है:

 FragmentManager fragmentManager = getSupportFragmentManager();
 //this will clear the back stack and displays no animation on the screen
 fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

17

मेरे लिए स्वीकृत उत्तर पर्याप्त नहीं था। मुझे उपयोग करना था:

FragmentManager fm = getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
    fm.popBackStackImmediate();
}

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

16

स्पष्ट छोरों के बिना बैकस्टैक

String name = getSupportFragmentManager().getBackStackEntryAt(0).getName();
getSupportFragmentManager().popBackStack(name, FragmentManager.POP_BACK_STACK_INCLUSIVE);

जहां नाम addToBackStack () पैरामीटर है

getSupportFragmentManager().beginTransaction().
                .replace(R.id.container, fragments.get(titleCode))
                .addToBackStack(name)

भले ही आप यू। रिप्लेसमेंट स्टैक जीवित हो लेकिन दृश्यमान नहीं होंगे
Asthme

8

मैं बस जोड़ना चाहता था: -

निम्नलिखित का उपयोग करके बैकस्ट से बाहर की ओर रोकना

fragmentManager.popBackStack ()

केवल लेन-देन से टुकड़े निकालने के बारे में है, यह स्क्रीन से टुकड़े को हटाने का कोई तरीका नहीं है। तो आदर्श रूप से, यह आपको दिखाई नहीं दे सकता है, लेकिन एक दूसरे के ऊपर दो या तीन टुकड़े हो सकते हैं, और बैक की प्रेस पर यूआई अव्यवस्थित, स्टैक्ड दिख सकता है।

बस एक सरल उदाहरण लेते हुए: -

मान लीजिए कि आपके पास एक टुकड़ा है जो Fragmnet B का उपयोग करके लोड करता है टुकड़ा करता है। करता है। इस लेनदेन को बचाने के लिए हम फिर से करते हैं। तो प्रवाह है: -

चरण 1 -> FragmentA-> FragmentB (हम FragmentB में चले गए, लेकिन Fragment A पृष्ठभूमि में है, दृश्यमान नहीं है)।

अब आप कुछ काम कर रहे हैं टुकड़ा में और सहेजें बटन दबाएं - जो सहेजने के बाद वापस खंड में जाना चाहिए।

चरण 2-> FragmentB को बचाने पर, हम वापस FragmentA पर जाते हैं।

चरण 3 -> इतनी सामान्य गलती होगी ... फ्रैग्मेंट बी में, हम फ्रैग्मेंटेशन के साथ टुकड़ा Manager.replace () टुकड़ा करेंगे।

लेकिन वास्तव में क्या हो रहा है, हम फिर से FragmentB की जगह Fragment A लोड कर रहे हैं। तो अब दो FragmentA हैं (एक STEP-1 से, और एक इस STEP-3 से)।

FragmentsA के दो उदाहरण एक दूसरे के ऊपर रखे गए हैं, जो कि दिखाई नहीं दे सकता है, लेकिन यह वहाँ है।

इसलिए भले ही हम उपरोक्त तरीकों से बैकस्टैक को स्पष्ट करते हैं, लेकिन लेन-देन को मंजूरी दे दी जाती है लेकिन वास्तविक अंशों को नहीं। तो आदर्श रूप से इस तरह के एक विशेष मामले में, सेव बटन के प्रेस पर आपको केवल fm.popBackStack () या करके टुकड़े में वापस जाने की आवश्यकता होती है fm.popBackImmediate ()

तो सही Step3-> fm.popBackStack () वापस टुकड़े में जाएं, जो पहले से ही मेमोरी में है।


3

दस्तावेज़ीकरण पढ़ना और अध्ययन करना कि टुकड़ा आईडी क्या है, यह बस स्टैक इंडेक्स प्रतीत होता है, इसलिए यह काम करता है:

fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);

शून्य (0 ) स्टैक का निचला भाग होता है, इसलिए इसमें पॉप अप करने से स्टैक साफ हो जाता है।

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

while(fragmentManager.getBackStackEntryCount() > 0) { fragmentManager.popBackStackImmediate(); }

1
fragmentManager..getBackStackEntryAt(0).getId()0 के बजाय का उपयोग कैसे करें ? यदि बैकस्टैक एंट्री आईडी स्टैक इंडेक्स से कुछ अलग है तो भी यह काम करना चाहिए।
क्राइस्टोफ

3

बस इस पद्धति का उपयोग करें और Context & Fragment टैग पास करें, जिसके लिए हमें बैकस्टेक अंशों को निकालना होगा।

प्रयोग

clearFragmentByTag(context, FragmentName.class.getName());



public static void clearFragmentByTag(Context context, String tag) {
    try {
        FragmentManager fm = ((AppCompatActivity) context).getSupportFragmentManager();

        for (int i = fm.getBackStackEntryCount() - 1; i >= 0; i--) {
            String backEntry = fm.getBackStackEntryAt(i).getName();
            if (backEntry.equals(tag)) {
                break;
            } else {
                 fm.popBackStack();
            }
        }
    } catch (Exception e) {
        System.out.print("!====Popbackstack error : " + e);
        e.printStackTrace();
    }
}

2

हाय ~ मुझे एक समाधान मिला जो बहुत बेहतर है: https://gist.github.com/ikew0ng/8297033

    /**
 * Remove all entries from the backStack of this fragmentManager.
 *
 * @param fragmentManager the fragmentManager to clear.
 */
private void clearBackStack(FragmentManager fragmentManager) {
    if (fragmentManager.getBackStackEntryCount() > 0) {
        FragmentManager.BackStackEntry entry = fragmentManager.getBackStackEntryAt(0);
        fragmentManager.popBackStack(entry.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }
}

2
कृपया अपने उत्तर का विस्तार करें कि यह समाधान क्यों बेहतर है।
साइमन.SA

यह उस तंत्र का उपयोग करता है जो sdk स्वयं प्रदान करता है, और कुछ npe समस्या पैदा नहीं करेगा।
चेनसी

1

मुझे यह काम इस तरह मिला:

public void showHome() {
    getHandler().post(new Runnable() {
        @Override
        public void run() {
            final FragmentManager fm = getSupportFragmentManager();
            while (fm.getBackStackEntryCount() > 0) {
                fm.popBackStackImmediate();
            }
        }
    });
}

1

यह मेरे लिए काम कर रहा है, इसे आज़माएं:

public void clearFragmentBackStack() {
        FragmentManager fm = getSupportFragmentManager();
        for (int i = 0; i < fm.getBackStackEntryCount() - 1; i++) {
            fm.popBackStack();
        }
    }

0
    private void clearBackStack(){
        SupportFragmentManaer fm = getSupportFragmentManager();
        fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

इस विधि के लिए कॉल बहुत साफ होगा।

  1. कोई लूप की आवश्यकता नहीं है।
  2. यदि आप टुकड़ों में एनीमेशन का उपयोग कर रहे हैं, तो यह बहुत सारे एनिमेशन नहीं दिखाएगा। लेकिन लूप का उपयोग करना होगा।

0
private boolean removeFragFromBackStack() {
    try {
        FragmentManager manager = getSupportFragmentManager();
        List<Fragment> fragsList = manager.getFragments();
        if (fragsList.size() == 0) {
            return true;
        }
        manager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

इस कोड स्निपेट के लिए धन्यवाद, जो कुछ सीमित, तत्काल सहायता प्रदान कर सकता है। एक उचित व्याख्या यह दर्शाती है कि यह समस्या का एक अच्छा समाधान क्यों है, यह बताकर इसके दीर्घकालिक मूल्य में बहुत सुधार करेगा और यह भविष्य के पाठकों के लिए अन्य, समान प्रश्नों के साथ अधिक उपयोगी होगा। कृपया कुछ स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें, जिसमें आपके द्वारा की गई धारणाएँ शामिल हैं।
अब्देलिलाह एल आइसाऊई
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.