Home » Android » android – How to avoid adding same fragment to stack

android – How to avoid adding same fragment to stack

Posted by: admin June 15, 2020 Leave a comment

Questions:

I need some help. em adding fragment to activity this way. problem is on each call of openFragment it create fragment and add. which is obvious. Question: what modification i do, so it can add fragment only once. on the next call with same fragment tag it will do nothing.

case: press button first time it add fragment and shows. i press again same button it response nothing.

public static void openFragment(Activity activity, Fragment fragment) {

    FragmentManager fragmentManager = ((ActionBarActivity) activity)
            .getSupportFragmentManager();
        FragmentTransaction ftx = fragmentManager.beginTransaction();
        ftx.addToBackStack(fragment.getClass().getSimpleName());
        ftx.setCustomAnimations(R.anim.slide_in_right,
                R.anim.slide_out_left, R.anim.slide_in_left,
                R.anim.slide_out_right);
        ftx.add(R.id.main_content, fragment);
        ftx.commit();
}
How to&Answers:

Here’s the solution, It will only allow you to add fragment once in stack otherwise it will pop-out the very same fragment from stack.

public static void openFragment(Activity activity, Fragment fragment) {
    String fragmentTag = fragment.getClass().getName();
    FragmentManager fragmentManager= ((ActionBarActivity) activity)
            .getSupportFragmentManager();

    boolean fragmentPopped = fragmentManager
            .popBackStackImmediate(fragmentTag , 0);

    if (!fragmentPopped && fragmentManager.findFragmentByTag(fragmentTag) == null) {

    FragmentTransaction ftx = fragmentManager.beginTransaction();
    ftx.addToBackStack(fragment.getClass().getSimpleName());
    ftx.setCustomAnimations(R.anim.slide_in_right,
            R.anim.slide_out_left, R.anim.slide_in_left,
            R.anim.slide_out_right);
    ftx.add(R.id.main_content, fragment);
    ftx.commit();
  }
}

slide_in_right

<?xml version="1.0" encoding="utf-8"?>
  <set xmlns:android="http://schemas.android.com/apk/res/android"
   android:shareInterpolator="true">
  <translate android:fromXDelta="100%"
    android:toXDelta="0%" android:fromYDelta="0%"
    android:toYDelta="0%" android:duration="200">
  </translate>
</set>

slide_out_right

<?xml version="1.0" encoding="utf-8"?>
   <set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate android:fromXDelta="0%" android:toXDelta="100%"
    android:fromYDelta="0%" android:toYDelta="0%"
    android:duration="200">
  </translate>
</set>

slide_in_left

<?xml version="1.0" encoding="utf-8"?>
  <set xmlns:android="http://schemas.android.com/apk/res/android"
  android:shareInterpolator="true">
  <translate android:fromXDelta="-100%"
    android:toXDelta="0%" android:fromYDelta="0%"
    android:toYDelta="0%" android:duration="200">
  </translate>
</set>

slide_out_left

<?xml version="1.0" encoding="utf-8"?>
 <set xmlns:android="http://schemas.android.com/apk/res/android"
  android:shareInterpolator="true">
  <translate android:fromXDelta="0%"
    android:toXDelta="-100%" android:fromYDelta="0%"
    android:toYDelta="0%" android:duration="200">
  </translate>
</set>

And this is how you call this function:

openFragment(activity, new MyFragment());

Answer:

Use FragmentTransaction.replace() instead of FragmentTransaction.add():

This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.

The first call to FragmentTransaction.replace() will simply add the fragment as there were no fragments to remove.

Answer:

check if fragment is already added or not by using this method:

if(!Fragment.isAdded()){
//add fragment
}

Answer:

Depending on your needs, there are multiple ways to approach this:

  1. Disable or remove the button after it’s clicked once.
  2. As @hidro suggested, use replace() instead of add() when calling the FragmentTransaction.
  3. Keep a List of string that will contain the class name of each fragment as it is added to the UI.

E.g.

List<String> fragments = new ArrayList<String>();

button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        FragmentTransaction ftx = fragmentManager.beginTransaction();
        ftx.add(R.id.main_content, fragment);
        ftx.commit();
        fragments.add(fragment.getClass().toString());
    }
});

Before adding the fragment using FragmenTransaction.commit() check if its class exists in the list and if it does, don’t add it.

Again, these 3 approaches work but which one will pick will depend on your app.

Answer:

To add a fragment only once,

You need to check every time before adding the fragment to backstack,
that if previously it is already added or not. If it is added already,
then you should pop that entry and add another entry.

So, you can do this using :

boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);

If fragmentPopped is true then there was a fragment added to backstack and itt is popped and you can add your fragment now to backstack. It is safe to call :

ftx.addToBackStack(fragment.getClass().getSimpleName());

If fragmentPopped is false then there was not any fragment added in backstack

Very nice information you can get : here

Answer:

You can use show() method of fragment transaction

 FragmentManager fragmentManager = ((ActionBarActivity) activity)
            .getSupportFragmentManager();
        FragmentTransaction ftx = fragmentManager.beginTransaction();

        ftx.setCustomAnimations(R.anim.slide_in_right,
                R.anim.slide_out_left, R.anim.slide_in_left,
                R.anim.slide_out_right);
    if(!fragment.isAdded())
    {
    //add fragment;
ftx.add(R.id.main_content, fragment).comit();
    }
    else
    {
   ftx.show(fragment).comit();
    }

Updated