代码之家  ›  专栏  ›  技术社区  ›  Mohsin

如何避免向堆栈中添加相同的片段

  •  8
  • Mohsin  · 技术社区  · 9 年前

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

    case:第一次添加片段并显示时按下按钮。我再次按下同一个按钮,它什么也没有反应。

    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();
    }
    
    6 回复  |  直到 9 年前
        1
  •  9
  •   Mohsin    8 年前

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

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

    向右滑动

    <?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>
    

    向右滑出

    <?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>
    

    滑入左侧

    <?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>
    

    滑出左侧

    <?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());
    
        2
  •  7
  •   hidro    9 年前

    使用 FragmentTransaction.replace() 而不是 FragmentTransaction.add() :

    这与调用 remove(Fragment) 对于所有当前添加的片段 containerViewId 然后 add(int, Fragment, String) 与这里给出的参数相同。

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

        3
  •  5
  •   Irfan Qureshi    7 年前

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

    if(!Fragment.isAdded()){
    //add fragment
    }
    
        4
  •  1
  •   Dzhuneyt marcinj    9 年前

    根据您的需要,有多种方法可以实现这一点:

    1. 单击一次后禁用或删除按钮。
    2. 正如@hidro所建议的,在调用FragmentTransaction时使用replace()而不是add()。
    3. 保留一个字符串列表,该列表将包含添加到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());
        }
    });
    

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

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

        5
  •  0
  •   Community kfsone    7 年前

    为了仅添加片段一次,

    在将片段添加到backstack之前,您需要每次检查, 如果之前已添加或未添加。如果已经添加, 那么您应该弹出该条目并添加另一个条目。

    因此,您可以使用:

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

    如果 fragmentPopped 真的 然后有一个片段被添加到backstack中,itt被弹出,您现在可以将片段添加到backback中。拨打以下电话是安全的:

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

    如果 碎片爆裂 假的 那么在backback中没有添加任何片段

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

        6
  •  0
  •   Hulk    9 年前

    可以使用片段事务的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();
        }
    

    已更新