5

我需要一些幫助。通過這種方式爲活動添加片段。問題是每次調用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(); 
} 

回答

5

下面是解決方案,它只允許您在堆棧中添加一次片段,否則會彈出堆棧中相同的片段。

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

請問,如何調用函數openFragment(???,newfragment)和動畫幻燈片的代碼xml ... – Webserveis 2016-02-19 20:42:12

+1

檢查更新 – user3819810 2016-02-22 06:32:26

5

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

本質上,這與調用remove(Fragment)用於添加具有相同containerViewId然後add(int, Fragment, String)這裏給出了相同的參數,所有當前添加片段。

第一次調用FragmentTransaction.replace()將簡單地添加片段,因爲沒有要刪除的片段。

+0

我不能使用,因爲有網絡的替換操作。所以每次訪問同一個片段都會再次花費我的請求。 – user3819810 2015-03-19 12:53:14

0

您可以使用顯示()片段交易

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

更新

+0

我用過它。但不工作。你能否根據我的代碼修改這張支票?謝謝 – user3819810 2015-03-19 12:32:53

+0

我修改了上面的內容,因爲你正在進行網絡通話,因此只有在創建片段時纔會進行一次網絡通話,一旦創建了片段,它只會在下次顯示時進行。在if語句中進行網絡調用。 – Hulk 2015-03-19 12:59:46

0

要添加一個片段只有一次的方法,

您需要添加片段前檢查每次backstack, ,如果以前它已經添加或沒有。如果它已被添加, 那麼你應該彈出該條目並添加另一個條目。

所以,你可以使用這樣做:

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

如果fragmentPopped再有就是加入到堆棧中和ITT彈出一個片段,你現在可以添加您的片段堆棧中。它是安全的呼籲:

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

如果fragmentPopped那麼有沒有在堆棧中添加任何片段

很不錯的信息,您可以得到:here

1

根據您的需求,有多種方法可以解決這個問題:

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

之前增加使用FragmenTransaction.commit(片段)檢查,如果在列表中存在的類,如果是的話,不添加它。

再一次,這3種方法的工作,但哪一個將選擇將取決於您的應用程序。

+0

我無法對所有按鈕執行此操作(禁用btn)。和替換而不是添加是不好的選擇,因爲我在每個片段上進行網絡操作,所以它花費我更多。如果沒有找到更好的答案,我期待第三名。謝謝 – user3819810 2015-03-19 12:43:55

1

檢查,如果片段通過使用這種方法已經添加或不:

if(!Fragment.isAdded()){ 
//add fragment 
} 
相關問題