बैकस्टैक में नवीनतम अंश प्राप्त करें


104

मैं बैकस्टैक में जोड़ दिया गया नवीनतम टुकड़ा उदाहरण कैसे प्राप्त कर सकता हूं (यदि मुझे टुकड़ा टैग और आईडी नहीं पता है)?

FragmentManager fragManager = activity.getSupportFragmentManager();
FragmentTransaction fragTransacion = fragMgr.beginTransaction();

/****After add , replace fragments 
  (some of the fragments are add to backstack , some are not)***/

//HERE, How can I get the latest added fragment from backstack ??

जवाबों:


156

आप एपीआई स्तर 14. में प्रस्तुत की गई getName()विधि का उपयोग कर सकते हैं FragmentManager.BackStackEntry। यह विधि एक टैग लौटाएगी, जिसका उपयोग आपने तब किया था जब आपने फ्रैगमेंट को बैकस्टैक के साथ जोड़ा था addTobackStack(tag)

int index = getActivity().getFragmentManager().getBackStackEntryCount() - 1
FragmentManager.BackStackEntry backEntry = getFragmentManager().getBackStackEntryAt(index);
String tag = backEntry.getName();
Fragment fragment = getFragmentManager().findFragmentByTag(tag);

आपको यह सुनिश्चित करने की आवश्यकता है कि आपने बैकस्टैक में इस तरह से टुकड़ा जोड़ा:

fragmentTransaction.addToBackStack(tag);

24
टैग द्वारा टुकड़ा खोजने के लिए इसे उसी टैग के साथ जोड़ा / बदला जाना चाहिए। FragmentTransaction.add(int containerViewId, Fragment fragment, String tag)या FragmentTransaction.replace(int containerViewId, Fragment fragment, String tag) डॉक्टर
साकिब

3
इसके साथ समस्या यह है कि यदि आपके पास बैक स्टैक में दो बार टुकड़ा है, तो आप एक विशिष्ट टुकड़ा प्राप्त नहीं कर सकते हैं जब आपके पास सभी इंडेक्स या बैकस्टेंट्री इकाई है।
जस्टिन

14
stackअगर मैं एक पॉप विधि के माध्यम से टुकड़े तक नहीं पहुंच सकता तो इसे कॉल करने का क्या मतलब है ?
केनी वर्डेन


1
मुझे पता नहीं क्यों लेकिन findFragmentByTag निरर्थक वापस आ रही है, तब भी जब डिबगर स्पष्ट रूप से दिखाता है कि टैग ठीक है।
htafoya

49
FragmentManager.findFragmentById(fragmentsContainerId) 

समारोह रिटर्न लिंक Fragmentबैकस्टैक में शीर्ष पर है। उपयोग उदाहरण:

    fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer);
            if(fr!=null){
                Log.e("fragment=", fr.getClass().getSimpleName());
            }
        }
    });

2
यह जवाब मेरी परियोजना में अच्छी तरह से काम करता है क्योंकि मैं मूल टुकड़े को पीछे के ढेर को छोड़कर हर टुकड़ा जोड़ता हूं। लेकिन मुझे लगता है कि यह जवाब काम नहीं करेगा यदि नवीनतम जोड़ा गया टुकड़ा बैकस्ट में जोड़ा नहीं गया था।
अर्ने एवरट्सन

40

मैंने उन कई समाधानों की कोशिश की और इस कार्य समाधान के साथ समाप्त हुआ:

इस उपयोगिता विधि को जोड़ें जो आपके बैकस्टैक में अंशों की संख्या प्राप्त करने के लिए नीचे कई बार उपयोग की जाएगी:

protected int getFragmentCount() {
    return getSupportFragmentManager().getBackStackEntryCount();
}

फिर, जब आप FragmentTransaction पद्धति का उपयोग करके अपने टुकड़े को जोड़ते / प्रतिस्थापित करते हैं, तो अपने टुकड़े के लिए एक अनूठा टैग बनाएं (जैसे: अपने ढेर में टुकड़ों की संख्या का उपयोग करके):

getSupportFragmentManager().beginTransaction().add(yourContainerId, yourFragment, Integer.toString(getFragmentCount()));

अंत में, आप इस विधि से अपने किसी भी टुकड़े को अपने बैकस्टैक में पा सकते हैं:

private Fragment getFragmentAt(int index) {
    return getFragmentCount() > 0 ? getSupportFragmentManager().findFragmentByTag(Integer.toString(index)) : null;
}

इसलिए, अपने बैकस्ट में शीर्ष टुकड़े लाने को आसानी से कॉल करके प्राप्त किया जा सकता है:

protected Fragment getCurrentFragment() {
    return getFragmentAt(getFragmentCount() - 1);
}

उम्मीद है की यह मदद करेगा!


10

इस सहायक विधि को ढेर के ऊपर से टुकड़ा मिलता है:

public Fragment getTopFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return getSupportFragmentManager().findFragmentByTag(fragmentTag);
}

1
धन्यवाद। सबसे सुंदर जवाब।
कोटलिन


6

टुकड़े करने वाले की सूची में टुकड़े करने वाला है। ध्यान रखें कि एक अंश को हटाने से, सूची का आकार कम नहीं होता है (टुकड़ा प्रविष्टि केवल शून्य हो जाती है)। इसलिए, एक वैध समाधान होगा:

public Fragment getTopFragment() {
 List<Fragment> fragentList = fragmentManager.getFragments();
 Fragment top = null;
  for (int i = fragentList.size() -1; i>=0 ; i--) {
   top = (Fragment) fragentList.get(i);
     if (top != null) {
       return top;
     }
   }
 return top;
}

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

नमस्ते, आपके समाधान के लिए धन्यवाद, लेकिन यह सुंदर और आसान नहीं है
मुहम्मद अली

मुझे संदेह है कि यह एक कार्यशील विलेय है। getFragments()टुकड़ों का एक छोटा संग्रह लौटाता है। शायद अंतिम एक दिखाई दे रहा है, लेकिन कई अन्य नहीं।
CoolMind

5

डीप गोयल द्वारा दिया गया जवाब मेरे लिए काम नहीं करता है क्योंकि मैं हमेशा सुस्त रहता हूं entry.getName();

मैं इस तरह से टुकड़े को एक टैग सेट करने के लिए क्या कर रहा हूँ:

ft.add(R.id.fragment_container, fragmentIn, FRAGMENT_TAG);

जहां ft मेरा टुकड़ा लेनदेन है और FRAGMENT_TAGटैग है। तब मैं इस कोड का उपयोग टुकड़ा प्राप्त करने के लिए करता हूं:

Fragment prev_fragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG);

यह केवल तभी काम करेगा जब आप सभी टुकड़े को एक ही टैग देंगे, जो कि बाद में एक विशिष्ट टुकड़ा खोजने के लिए एक अच्छा विचार नहीं है।
शिरनी Sh५

4

बस @ सरगोई होसैनी (सही) उत्तर लिया और कोटलिन में 2017 में उन लोगों के लिए इसे बनाया :)

fun getTopFragment(): Fragment? {
    supportFragmentManager.run {
        return when (backStackEntryCount) {
            0 -> null
            else -> findFragmentByTag(getBackStackEntryAt(backStackEntryCount - 1).name)
        }
    }
}

* यह एक गतिविधि के अंदर से बुलाया जाना चाहिए।

का आनंद लें :)


3

आप getBackStackEntryAt () का उपयोग कर सकते हैं । यह जानने के लिए कि बैकस्टैक में आप कितनी एंट्री लेते हैं, आप getBackStackEntryCount () का उपयोग कर सकते हैं।

int lastFragmentCount = getBackStackEntryCount() - 1;

11
लेकिन मैं बैकस्टैक में आखिरी टुकड़ा कैसे प्राप्त कर सकता हूं ?? PopBackStackEntryAt () केवल एक BackStackEntry उदाहरण देता है, खंड नहीं
Leem.fin

हाँ, आप सही हैं, लेकिन हर BackStackEntry होल्ड और आईडी है जिसे आप getId () के साथ पुनः प्राप्त कर सकते हैं। आप इस आईडी का उपयोग टुकड़े को पुनः प्राप्त करने के लिए कर सकते हैं
ब्लैकबेल्ट

1
अंतिम टुकड़ा प्राप्त करने के लिए: getBackStackEntryCount () - 1
एक-

3
यह उत्तर गलत है, मैं देख रहा हूं कि बैकस्टैक प्रविष्टियों में 0 की आईडी है, इसलिए आईडी द्वारा टुकड़े को पुनः प्राप्त नहीं किया जा सकता है।
जस्टिन

1
यह पुराना है, लेकिन किसी के लिए जो यहां भटकता है: बैक स्टैक के टुकड़े नहीं हैं, लेकिन टुकड़े के लेन-देन हैं, यही कारण है कि यह उत्तर गलत है
maciekjanusz

3

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

getSupportFragmentManager.beginTransaction().replace(R.id.container_id,FragmentName,TAG_NAME).addToBackStack(TAG_NAME).commit();

आपको एक ही टैग को दो बार जोड़ना होगा।

मैंने टिप्पणी की होगी, लेकिन मेरे पास 50 प्रतिष्ठा नहीं है।


अब आपको 50 मिल गए :)
davidbilla

2

अपनी खुद की बैक स्टैक रखें myBackStack:। आप के लिए Addएक टुकड़ा के रूप में FragmentManager, यह भी करने के लिए जोड़ें myBackStack। में onBackStackChanged()से पॉप myBackStackजब इसकी लंबाई से अधिक है getBackStackEntryCount


2

लगता है कि कुछ बेहतर के लिए बदल गया है, क्योंकि नीचे दिए गए कोड मेरे लिए पूरी तरह से काम करते हैं, लेकिन मुझे पहले से ही दिए गए जवाबों में यह नहीं मिला।

Kotlin:

supportFragmentManager.fragments[supportFragmentManager.fragments.size - 1]

जावा:

getSupportFragmentManager().getFragments()
.get(getSupportFragmentManager().getFragments().size() - 1)

2

यदि आप उपयोग करते हैं addToBackStack(), तो आप निम्नलिखित कोड का उपयोग कर सकते हैं।

List<Fragment> fragments = fragmentManager.getFragments(); activeFragment = fragments.get(fragments.size() - 1);


1

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

यदि आप वास्तव में टुकड़ों का ढेर FragmentManagerलगाना चाहते हैं और ढेर में इसके सूचकांक द्वारा एक टुकड़े का उपयोग करने में सक्षम होना चाहते हैं, तो आपके पास और इसके बैकस्ट पर एक अमूर्त परत होगी। यहाँ आप इसे कैसे कर सकते हैं:

public class FragmentStackManager {
  private final FragmentManager fragmentManager;
  private final int containerId;

  private final List<Fragment> fragments = new ArrayList<>();

  public FragmentStackManager(final FragmentManager fragmentManager,
      final int containerId) {
    this.fragmentManager = fragmentManager;
    this.containerId = containerId;
  }

  public Parcelable saveState() {
    final Bundle state = new Bundle(fragments.size());
    for (int i = 0, count = fragments.size(); i < count; ++i) {
      fragmentManager.putFragment(state, Integer.toString(i), fragments.get(i));
    }
    return state;
  }

  public void restoreState(final Parcelable state) {
    if (state instanceof Bundle) {
      final Bundle bundle = (Bundle) state;
      int index = 0;
      while (true) {
        final Fragment fragment =
            fragmentManager.getFragment(bundle, Integer.toString(index));
        if (fragment == null) {
          break;
        }

        fragments.add(fragment);
        index += 1;
      }
    }
  }

  public void replace(final Fragment fragment) {
    fragmentManager.popBackStackImmediate(
        null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    fragmentManager.beginTransaction()
        .replace(containerId, fragment)
        .addToBackStack(null)
        .commit();
    fragmentManager.executePendingTransactions();

    fragments.clear();
    fragments.add(fragment);
  }

  public void push(final Fragment fragment) {
    fragmentManager
        .beginTransaction()
        .replace(containerId, fragment)
        .addToBackStack(null)
        .commit();
    fragmentManager.executePendingTransactions();

    fragments.add(fragment);
  }

  public boolean pop() {
    if (isEmpty()) {
      return false;
    }

    fragmentManager.popBackStackImmediate();

    fragments.remove(fragments.size() - 1);
    return true;
  }

  public boolean isEmpty() {
    return fragments.isEmpty();
  }

  public int size() {
    return fragments.size();
  }

  public Fragment getFragment(final int index) {
    return fragments.get(index);
  }
}

अब बजाय जोड़ने और फोन करके टुकड़े को दूर करने के FragmentManagerलिए सीधे, आप का उपयोग करना चाहिए push(), replace()और pop()के तरीकों FragmentStackManager। और आप केवल कॉल करके सबसे ऊपरी टुकड़े तक पहुंच सकेंगे stack.get(stack.size() - 1)

लेकिन अगर आपको हैक करना पसंद है, तो मुझे इसी तरह के काम करने के अन्य तरीके अपनाने होंगे। मुझे केवल एक बात का उल्लेख करना है कि ये हैक केवल समर्थन अंशों के साथ काम करेंगे।

पहला हैक केवल सभी सक्रिय अंशों को टुकड़े प्रबंधक में जोड़ा जाना है। यदि आप केवल एक-एक करके टुकड़ों को प्रतिस्थापित करते हैं और स्टैक से पॉप करते हैं तो यह विधि सबसे ऊपर का टुकड़ा लौटाएगी:

public class BackStackHelper {
  public static List<Fragment> getTopFragments(
      final FragmentManager fragmentManager) {
    final List<Fragment> fragments = fragmentManager.getFragments();
    final List<Fragment> topFragments = new ArrayList<>();

    for (final Fragment fragment : fragments) {
      if (fragment != null && fragment.isResumed()) {
        topFragments.add(fragment);
      }
    }

    return topFragments;
  }
}

दूसरा तरीका ईवेंट को अधिक हैक किया गया है और आपको अंतिम लेन-देन में जोड़े गए सभी अंशों को प्राप्त करने की अनुमति देता है, जिनके लिए addToBackStackकॉल किया गया है:

package android.support.v4.app;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class BackStackHelper {
  public static List<Fragment> getTopFragments(
      final FragmentManager fragmentManager) {
    if (fragmentManager.getBackStackEntryCount() == 0) {
      return Collections.emptyList();
    }

    final List<Fragment> fragments = new ArrayList<>();

    final int count = fragmentManager.getBackStackEntryCount();
    final BackStackRecord record =
        (BackStackRecord) fragmentManager.getBackStackEntryAt(count - 1);
    BackStackRecord.Op op = record.mHead;
    while (op != null) {
      switch (op.cmd) {
        case BackStackRecord.OP_ADD:
        case BackStackRecord.OP_REPLACE:
        case BackStackRecord.OP_SHOW:
        case BackStackRecord.OP_ATTACH:
          fragments.add(op.fragment);
      }
      op = op.next;
    }

    return fragments;
  }
}

कृपया ध्यान दें कि इस मामले में आपको इस वर्ग को android.support.v4.appपैकेज में रखना होगा ।


0

या आप केवल एक टैग जोड़ सकते हैं जब उनकी सामग्री के अनुरूप टुकड़े जोड़ सकते हैं और सरल स्थिर स्ट्रिंग फ़ील्ड का उपयोग कर सकते हैं (आप इसे अंतिम बार विखंडन टैग को रखने के लिए onSaveInstanceState (बंडल) विधि में गतिविधि उदाहरण बंडल में सहेज सकते हैं और यह टुकड़ा बायटैग प्राप्त कर सकते हैं) किसी भी समय आपको चाहिए ...


0

उच्चतम (दीपक गोयल) जवाब मेरे लिए अच्छा काम नहीं किया। किसी तरह टैग ठीक से जोड़ा नहीं गया था।

मैंने प्रवाह के माध्यम से टुकड़े का आईडी भेजना (इरादों का उपयोग करना) समाप्त कर दिया और इसे सीधे खंड प्रबंधक से प्राप्त किया।

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