ব্যাকস্ট্যাকের সর্বশেষতম খণ্ডটি পান


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

আপনি এপিআই স্তরে যে getName()পদ্ধতিটি FragmentManager.BackStackEntryপ্রবর্তিত হয়েছিল সেটিকে ব্যবহার করতে পারেন 14. আপনি যখন ব্যাকস্ট্যাকের সাথে ফ্রেগমেন্ট যুক্ত করেছিলেন তখন এই পদ্ধতিটি এমন একটি ট্যাগ দেবে যা আপনি ব্যবহার করেছিলেন 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
আমি কেন জানি না তবে ফ্রেগমেন্টবাইটাগ নালায় ফিরছে, এমনকি যখন ডিবাগারটি পরিষ্কারভাবে দেখায় যে ট্যাগটি ঠিক আছে।
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();
}

তারপরে, আপনি যখন ফ্রেগমেন্ট ট্রান্সজেকশন পদ্ধতিটি ব্যবহার করে আপনার টুকরো যোগ / প্রতিস্থাপন করবেন তখন আপনার খণ্ডে একটি অনন্য ট্যাগ তৈরি করুন (উদাহরণস্বরূপ: আপনার স্ট্যাকের টুকরো সংখ্যা ব্যবহার করে):

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
ধন্যবাদ। সবচেয়ে মার্জিত উত্তর। তা এখানে Kotlin প্রেমীদের জন্য যোগ করা হয়েছে stackoverflow.com/a/47336504/1761406
Shirane85


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
নির্ভরযোগ্য না. তিনটি কারণ: ১) এটি খণ্ডের ব্যবস্থাপক কেবল স্ট্যাকের মধ্যে নয়, সেগুলি সম্পর্কে জানেন এমন সমস্ত খণ্ডের একটি তালিকা। 2) কোনও খণ্ডন নেই যে খণ্ড খণ্ডকের ম্যানেজার তালিকার শেষে নতুনদের যুক্ত করে রাখবে। অবশ্যই, এটি সাধারণ পরীক্ষায় এটি করবে, তবে যদি কোনও অংশ নষ্ট হয়ে যায়, একটি শূন্যস্থান ছেড়ে যায় এবং তারপরে কিছু পরিস্থিতিতে খণ্ডের ব্যবস্থাপক সেই খালি স্লটটিকে পুনরায় ব্যবহার করার সিদ্ধান্ত নেন? এটি করে না বলছেন, তবে কোনও পরিস্থিতিতে এটি কোনও দিনই হবে না এমন কোনও গ্যারান্টি নেই। 3) যদি আপনি বা ভবিষ্যতের কোনও প্রোগ্রামার টুকরো পরিচালনা করতে সংযুক্ত / বিচ্ছিন্নতা ব্যবহার শুরু করেন তবে এটি স্ট্যাকের সাথে মেলে না।
টুলমেকারস্টেভ

হাই, আপনার সমাধানের জন্য ধন্যবাদ তবে এটি সুন্দর এবং সহজ নয়
মুহাম্মদ আলী

আমি সন্দেহ করি এটি একটি কর্মক্ষম দ্রাবক। getFragments()খণ্ডগুলির একটি সংক্ষিপ্ত সংগ্রহ প্রদান করে returns সম্ভবত শেষটি দৃশ্যমান তবে অন্য অনেকে নয়।
কুলমাইন্ড

5

ডিপাক গোয়েলের দেওয়া উত্তর আমার পক্ষে কাজ করে না কারণ আমি সর্বদা এলোমেলো হয়ে যাই entry.getName();

আমি যা করি তা হ'ল খণ্ডে কোনও ট্যাগ সেট করা:

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

যেখানে ft হল আমার খণ্ডের লেনদেন এবং FRAGMENT_TAGতা ট্যাগ। তারপরে আমি খণ্ডটি পেতে এই কোডটি ব্যবহার করি:

Fragment prev_fragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG);

আপনি কেবলমাত্র সমস্ত খণ্ডকে একই ট্যাগ দিলে এটি কাজ করবে, আপনি যদি পরে কোনও নির্দিষ্ট খণ্ড খুঁজতে চান তবে এটি ভাল ধারণা নয়।
শিরেন 85

4

সবেমাত্র @rohayeh होस्সিইনি (সঠিক) উত্তর নিয়েছে এবং 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
তবে আমি কীভাবে ব্যাকস্ট্যাকের শেষ টুকরোটি পেতে পারি ?? পপব্যাকস্ট্যাকএন্ট্রিআউট () কেবল একটি ব্যাকস্ট্যাকএন্ট্রি উদাহরণ দেয়, খণ্ড না
লিম.ফিন

হ্যাঁ আপনি ঠিক বলেছেন, তবে প্রতিটি ব্যাকস্ট্যাক এন্ট্রি হোল্ড করে এবং আইডি যা আপনি getId () দিয়ে পুনরুদ্ধার করতে পারবেন। আপনি এই আইডিটি খণ্ডটি পুনরুদ্ধার করতে ব্যবহার করতে পারেন
ব্ল্যাকবেল্ট

1
1 - getBackStackEntryCount (): গত টুকরা পেতে
আন-Droid

3
এই উত্তরটি ভুল, আমি দেখছি ব্যাকস্ট্যাক এন্ট্রিগুলিতে 0 এর আইডি রয়েছে, সুতরাং আইডি দ্বারা খণ্ডটি পুনরুদ্ধার করতে পারবেন না।
জাস্টিন

1
এটি পুরানো, তবে যে কেউ এখানে ঘুরে বেড়ায়: পিছনে স্ট্যাক টুকরো টুকরো করে না, তবে খণ্ডের লেনদেন করে, এই কারণেই এই উত্তরটি ভুল
maciekjanusz

3

আমি দীপক গোয়েলের উত্তরে কিছু যুক্ত করব যেহেতু আমার অন্তর্ভুক্ত প্রচুর লোক তার পদ্ধতিটি ব্যবহার করে শূন্য হয়ে যাচ্ছিল। স্পষ্টতই আপনি ট্যাগ স্ট্রাক্টটিতে একটি টুকরো যোগ করার সময় ট্যাগটি তৈরি করার জন্য আপনার এটি করা উচিত:

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

আপনার একই ট্যাগটি দুটিবার যুক্ত করা দরকার।

আমি মন্তব্য করতাম তবে আমার 50 টি খ্যাতি নেই।


আপনি এখন 50 পেয়ে
গেছেন

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

সর্বোচ্চ (দীপক গোয়েল) উত্তর আমার পক্ষে ভাল কাজ করে নি। কোনওভাবে ট্যাগটি সঠিকভাবে যুক্ত করা হয়নি।

আমি কেবল প্রবাহের মাধ্যমে খণ্ডের আইডি প্রেরণ করে (উদ্দেশ্যগুলি ব্যবহার করে) এবং সরাসরি খণ্ড পরিচালকের কাছ থেকে এটি পুনরুদ্ধার করেছিলাম।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.