अपने आप को हटाने के लिए एक फ्रैगमेंट कैसे प्राप्त करें, अर्थात् इसके खत्म होने के बराबर ()?


230

मैं संगतता लाइब्रेरी का उपयोग करके टुकड़ों का उपयोग करने के लिए एक ऐप परिवर्तित कर रहा हूं। अब वर्तमान में मेरे पास कई गतिविधियाँ हैं (ABCD) जो एक दूसरे पर श्रृंखला बनाती हैं, D में एक बटन 'OK' होता है जिसे जब दबाया हुआ कॉल खत्म होता है तो onActivityResult()इसके बाद C और B को नष्ट कर देता है।

मेरे पूर्व Honycomb टुकड़ा संस्करण के लिए प्रत्येक गतिविधि प्रभावी रूप से टुकड़े Af Bf Cf Df पर एक आवरण है। सभी गतिविधियों के माध्यम से startActivityForResult()और onActivityResult()प्रत्येक टुकड़े के भीतर खुशी से कॉल किया जा सकता हैgetActivity().finish()

हालांकि जो समस्या मुझे हो रही है वह मेरे हनीकॉम्ब संस्करण में है, मेरे पास केवल एक गतिविधि है, ए, और टुकड़े बीएफ, सीएफ, डीएफ का उपयोग करके लोड किए गए हैं FragmentManager

डीएफ, सीएफ, और बीएफ के अंशों को हटाने के लिए 'ओके' दबाए जाने पर मुझे समझ में नहीं आता कि डीएफ में क्या करना है?

मैंने खुद को स्टैक से अलग करने की कोशिश की, लेकिन इसका एक अपवाद था। onActivityResult()बेकार है क्योंकि मैंने टुकड़े का उपयोग करके लोड नहीं किया है startActivityForResult()

क्या मैं इस बारे में पूरी तरह से गलत सोच रहा हूं? क्या मुझे किसी प्रकार के श्रोता को लागू करना चाहिए जो लेनदेन प्रबंधक का उपयोग कर पॉप करने के लिए माता-पिता के टुकड़े या गतिविधि के साथ संवाद करता है?


7
के बारे में क्या ((YourActivity) getActivity ()) onBackPressed ();
विश्वनाथ लीक्षमान

@ViswanathLekshmanan आपकी टिप्पणी का उत्तर मेरे लिए उपयोगी है .. मेरे बारे में 1 अपडेट
अभिषेक सिंह

@AbhishekSingh सुनकर अच्छा लगा :)
विश्वनाथ लीक्षमान

@ViswanathLekshmanan :)
अभिषेक सिंह

जवाबों:


62

डीएफ, सीएफ, और बीएफ के अंशों को हटाने के लिए 'ओके' दबाए जाने पर मुझे समझ में नहीं आता कि डीएफ में क्या करना है?

चरण # 1: क्या D ने D को बताया "यो! हमें ठीक क्लिक मिला है!" एक विधि के माध्यम से, या तो गतिविधि पर, या गतिविधि द्वारा आपूर्ति की गई एक इंटरफ़ेस उदाहरण पर कॉल करके।

चरण # 2: D ने अंशों को हटा दिया है FragmentManager

होस्टिंग गतिविधि (डी) वह है जो जानता है कि गतिविधि में अन्य टुकड़े क्या हैं (बनाम अन्य गतिविधियों में)। इसलिए, टुकड़े-टुकड़े की घटनाओं को प्रभावित करने वाले टुकड़े को गतिविधि के लिए प्रचारित किया जाना चाहिए, जो उचित ऑर्केस्ट्रेशन चालें करेगा।


लेकिन मेरे हनीकॉम्ब संस्करण में कोई डी नहीं है, यह मेरी मुश्किल है। बस एक एक्टिविट A है, जो खंड Bf को लोड करता है, जो Cf को लोड करता है, जो FragmentTransaction का उपयोग करके Df को लोड करता है।
PJL

1
@PJL: क्षमा करें, मेरा मतलब था कि ए। यह एक श्रोता इंटरफ़ेस का उपयोग करने का एक कारण है, इसलिए कई गतिविधियाँ डीएफ से "हमें ठीक क्लिक मिला" घटना का जवाब दे सकती हैं।
कॉमन्सवेयर

1
जैसा कि मैं वर्तमान में पोर्ट कर रहा हूं मैंने खंडों से डीए की onActivityResult विधि से एक श्रोता विधि को कॉल किया है, जिसमें गतिविधि है जिसके बाद मैंने फ्रैगमेंटमैन पर पॉपबैकस्टैक कहा। हालाँकि, इस परिणाम में "IllegalStateException: onSaveInstanceState 'के बाद यह कार्रवाई नहीं की जा सकती है। मैं इसे कैसे दूर कर सकता हूं? कोई भी विचार?
PJL

1
@DiegoPalomar: finish()पर्याप्त होना चाहिए।
कॉमन्सवेयर

1
@ user3364963: जब मैंने जांच की थी, तब से कुछ समय हो गया है, लेकिन IIRC, इसे तब नष्ट कर दिया जाता है जब यह बैक स्टैक से पॉप अप हो जाता है। onDestroy()अपने टुकड़े करने के लिए एक विधि जोड़ें और देखें कि क्या यह कहा जाता है।
कॉमन्सवेयर

313

हालांकि यह सबसे अच्छा दृष्टिकोण नहीं हो सकता है निकटतम समतुल्य मैं सोच सकता हूं कि यह कार्य समर्थन / संगतता पुस्तकालय के साथ है

getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();

या

getActivity().getFragmentManager().beginTransaction().remove(this).commit();

अन्यथा।

इसके अलावा आप बैकस्ट का उपयोग कर सकते हैं और इसे पॉप कर सकते हैं। हालाँकि यह ध्यान रखें कि टुकड़ा बैकस्टैक पर नहीं हो सकता है (यह वहां मिले टुकड़े के आधार पर ..) या यह अंतिम नहीं हो सकता है जो स्टैक पर मिला है इसलिए स्टैक को पॉप करने से गलत को हटाया जा सकता है ...


11
हालांकि यह दृष्टिकोण काम करता है, यदि आप addToBackStack (नल) का उपयोग कर रहे हैं तो यह पीछे के बटन हैंडलर +1 को छोड़ देगा। तो आपको इसे दो बार दबाना होगा।
user123321 1

34
FragmentManager से "पॉप" टुकड़ा।
18:123 पर user123321

2
मैंने उपरोक्त प्रक्रिया की कोशिश की है, लेकिन यह त्रुटि दे रहा है "जावा-लैंग-अवैधस्टैटेक्स्टैप्शन-कैन-नॉट-परफॉर्मेंस-एक्शन-आफ्टर-कनस्टीवेंस।" तो जहां मुझे वास्तव में टुकड़ा को दूर करना है
KK_07k11A0585

6
यह उत्तर एक बुरा अभ्यास है और इसे वोट नहीं मिलना चाहिए। फ्रेगमेंट का मतलब इस तरह आत्म-जागरूक होना नहीं है। यह पुन: प्रयोज्य को मारता है, जो टुकड़ों का बिंदु है! टुकड़े को किसी भी माध्यम से निकालने के लिए गतिविधि को संकेत देना चाहिए। कॉलबैक इंटरफ़ेस विधि एक लोकप्रिय विकल्प है। developer.android.com/training/basics/fragments/…
colintheshots

2
@ मैनफ्रेडमोसर मैं असहमत हूं। यह बहुत सवाल का बिंदु है। उसके पास टुकड़ों को हटाने का पूरा क्रम है। इस कोड में गतिविधि संलग्न है या नहीं, इसके लिए कोई शून्य जाँच या जाँच नहीं है। यह उत्पादन में टूट जाएगा क्योंकि यह बहुत सी चीजों पर निर्भर करता है जो एक टुकड़ा नहीं जानता है।
कोलींथेशॉट्स 19

263

आप नीचे दिए गए दृष्टिकोण का उपयोग कर सकते हैं, यह ठीक काम करता है:

getActivity().getSupportFragmentManager().popBackStack();

44
यह उत्तर स्वीकृत की तुलना में 10 गुना बेहतर है - सीधे बिंदु पर।
nikib3ro

50
यह भी स्वीकृत डिजाइन की तुलना में 10 गुना खराब है। एक टुकड़ा एक गतिविधि के लिए एक छोटा "सहायक" माना जाता है और इसे कभी भी खुद या अन्य टुकड़ों पर नियंत्रण में नहीं होना चाहिए
पैट्रिक

6
समाधान सही नहीं है क्योंकि @avalancha ने बताया। पर एक नज़र डालें developer.android.com/guide/components/...
the_dark_destructor

2
मैं onActivityResult और त्रुटि हो रही है "onSaveInstanceState के बाद यह क्रिया नहीं कर सकता" इस पद्धति का उपयोग कर रहा हूं। मैं इसे कैसे हल कर सकता हूं?
जयेशकुमार सोजित्रा

1
popBackStack()एक ही समाधान है जो तब काम करता है जब आप खंड को हटाने के बाद क्रिया पट्टी शीर्षक को पिछली स्थिति में वापस सेट करना चाहते हैं। अन्यथा मुझे stackoverflow.com/questions/13472258/… से दोनों उच्च रेटेड समाधानों को संयोजित करने की आवश्यकता नहीं होगी और यह समाधान विभिन्न उपयोग मामलों के बाद हमेशा उचित एक्शन बार शीर्षक सेट करने के लिए यहाँ है। जैसे बैक प्रेस करना, डिलीट करना, रिप्लेसिंग जोड़ना, वगैरह।
बेवेर

36

आपको फ्रैगमेंट को जोड़ने और हटाने के साथ गतिविधि को करने देना चाहिए, जैसा कि कॉमन्सवेयर कहता है, एक श्रोता का उपयोग करें। यहाँ एक उदाहरण है:

public class MyActivity extends FragmentActivity implements SuicidalFragmentListener {

    // onCreate etc

    @Override
    public void onFragmentSuicide(String tag) {
        // Check tag if you do this with more than one fragmen, then:
        getSupportFragmentManager().popBackStack();
    }
}

public interface SuicidalFragmentListener {
    void onFragmentSuicide(String tag);
}

public class MyFragment extends Fragment {

    // onCreateView etc

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
           suicideListener = (SuicidalFragmentListener) activity;
        } catch (ClassCastException e) {
           throw new RuntimeException(getActivity().getClass().getSimpleName() + " must implement the suicide listener to use this fragment", e);
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // Attach the close listener to whatever action on the fragment you want
        addSuicideTouchListener();
    }

    private void addSuicideTouchListener() {
        getView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              suicideListener.onFragmentSuicide(getTag());
            }
        });
    }
}

5
आत्महत्या ज्यादा इमो स्टाइल? कैसे "SelfClosing" या "AutoClose" या "SmartClose" (r) के बारे में
DritanX

21
यह बंद करने नहीं कर रहा है यह है हमेशा के लिए मर ;-(
ब्लंडेल

3
यह अन्य उत्तरों की तुलना में बहुत क्लीनर दृष्टिकोण है। गतिविधि टुकड़ा बनाता है और प्रस्तुत करता है, और इसके जीवनचक्र को नियंत्रित करना चाहिए। जब ऐसा कुछ होता है जो इंगित करता है कि टुकड़ा अब दृश्य में नहीं होना चाहिए, तो उसे गतिविधि को बताना चाहिए और गतिविधि को निकालने देना चाहिए।
क्रिस्टोफर पिक्सले

7
तकनीकी तौर पर, अगर हमें गतिविधि को खंड को मारना है, तो टुकड़ा आत्मघाती नहीं है। गतिविधि समलैंगिक है।
केसी मरे

17

गतिविधि / AppCompatActivity में:

@Override
public void onBackPressed() {
    if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
        // if you want to handle DrawerLayout
        mDrawerLayout.closeDrawer(GravityCompat.START);
    } else {
        if (getFragmentManager().getBackStackEntryCount() == 0) {
            super.onBackPressed();
        } else {
            getFragmentManager().popBackStack();
        }
    }
}

और फिर खंड में कॉल करें:

getActivity().onBackPressed();

या अन्य उत्तरों में कहा गया है, इसे खंड में कॉल करें:

getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();

5

यदि आप नए नेविगेशन घटक का उपयोग कर रहे हैं, तो जैसा कि सरल है

findNavController().popBackStack()

यह आपके लिए सभी FragmentTransaction को पीछे कर देगा।


4

देखें कि क्या आपकी ज़रूरतें एक DialogFragment से पूरी होती हैं। DialogFragment में एक खारिज () विधि है। मेरी राय में बहुत क्लीनर।


3

मैं उसके लिए सरल विधि बनाता हूं

popBackStack(getSupportFragmentManager());

इसे मेरे एक्टिविटी यूटिल्स क्लास में रखें

public static void popBackStack(FragmentManager manager){
        FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
        manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

यह बहुत अच्छा है, मज़े करो!


2
मुझे आपकी विधि का उद्देश्य नहीं मिला। मूल popBackStack पूरी तरह से पर्याप्त लगता है।
अविश्वसनीय जनवरी

1

OnCreate:

//Add comment fragment
            container = FindViewById<FrameLayout>(Resource.Id.frmAttachPicture);
            mPictureFragment = new fmtAttachPicture();

            var trans = SupportFragmentManager.BeginTransaction();
            trans.Add(container.Id, mPictureFragment, "fmtPicture");
            trans.Show(mPictureFragment); trans.Commit();

यह है कि मैं क्लिक इवेंट 1 में टुकड़े को कैसे छुपाता हूं

//Close fragment
    var trans = SupportFragmentManager.BeginTransaction();
    trans.Hide(mPictureFragment);
    trans.AddToBackStack(null);
    trans.Commit();

फिर इसे वापस int घटना 2 दिखाता है

var trans = SupportFragmentManager.BeginTransaction();
            trans.Show(mPictureFragment); trans.Commit();

1

यदि आपको बैकस्टैक इतिहास में चौथे टुकड़े से पहले पॉपबैक करने की आवश्यकता है, तो टैग का उपयोग करें !!!

जब आप पहला टुकड़ा जोड़ते हैं तो आपको कुछ इस तरह का उपयोग करना चाहिए:

getFragmentManager.beginTransaction.addToBackStack("A").add(R.id.container, FragmentA).commit() 

या

getFragmentManager.beginTransaction.addToBackStack("A").replace(R.id.container, FragmentA).commit()

और जब आप Fragments B, C और D दिखाना चाहते हैं, तो आप इसका उपयोग करें:

getFragmentManager.beginTransaction.addToBackStack("B").replace(R.id.container, FragmentB, "B").commit()

और अन्य पत्र ....

Fragmentए पर लौटने के लिए , बस कॉल करें popBackStack(0, "A"), हाँ, उस ध्वज का उपयोग करें जिसे आपने निर्दिष्ट किया था जब आप इसे जोड़ते हैं, और ध्यान दें कि यह कमांड में एक ही ध्वज होना चाहिए addToBackStack(), न कि कमांड में प्रयुक्त कोई व्यक्ति प्रतिस्थापित या जोड़ें।

आपका स्वागत है ;)


मैंने 'popBackStack (0, "A") का परीक्षण किया है और मेरा ऐप वापस A के टुकड़े में आ गया है, लेकिन मैं केवल यही चाहता हूं कि टुकड़ा वापस Stack से हटा दिया जाएगा ... मैं स्क्रीन में दिखाए बिना Stack से टुकड़ा कैसे निकाल सकता हूं ??
क्रिअंक

1

एक ही टुकड़े के अंदर एक टुकड़ा बंद करने के लिए

getActivity().onBackPressed();

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