How to avoid adding same fragment to stack

老子叫甜甜 提交于 2019-12-23 08:45:08

问题


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();
}

回答1:


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());



回答2:


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.




回答3:


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

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



回答4:


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.




回答5:


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




回答6:


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



来源:https://stackoverflow.com/questions/29144341/how-to-avoid-adding-same-fragment-to-stack

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!