如何避免将相同的片段添加到堆栈

How to avoid adding same fragment to stack

我需要一些帮助。 em 以这种方式将片段添加到 activity。问题是在每次调用 openFragment 时它都会创建片段并添加。这是显而易见的。问题:我做了什么修改,所以它只能添加一次片段。在下一次使用相同片段标签的调用中,它什么都不做。

案例:第一次按下按钮添加片段并显示。我再次按下相同的按钮,它没有任何反应。

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

使用FragmentTransaction.replace()代替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.

第一次调用 FragmentTransaction.replace() 将简单地添加片段,因为没有要删除的片段。

可以使用片段交易的show()方法

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

已更新

只添加一次片段,

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.

因此,您可以使用:

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

如果 fragmentPoppedtrue 那么有一个片段被添加到 backstack 并且 itt 被弹出,你现在可以将你的片段添加到 backstack。打电话是安全的:

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

如果fragmentPoppedfalse那么没有任何片段被添加到backstack

您可以获得非常好的信息:here

根据您的需要,有多种方法可以解决这个问题:

  1. 单击一次后禁用或删除按钮。
  2. 正如@hidro 所建议的那样,在调用 FragmentTransaction 时使用 replace() 而不是 add()。
  3. 保留一个字符串列表,其中包含每个片段的 class 名称,因为它被添加到 UI。

例如

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

在使用 FragmenTransaction.commit() 添加片段之前,检查其 class 是否存在于列表中,如果存在,则不要添加它。

同样,这 3 种方法都有效,但选择哪一种将取决于您的应用。

这是解决方案,它只允许您在堆栈中添加一次片段,否则它会从堆栈中弹出完全相同的片段。

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>

这就是您调用此函数的方式:

openFragment(activity, new MyFragment());

使用此方法检查是否已添加片段:

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