2013-08-01 88 views
0

我使用MainActivity來管理多個片段的顯示。我有一個showFragment方法迭代通過我的片段數組,並顯示/隱藏它們,並相應地設置backstack。問題是,只要按下後退按鈕,HomeFrag就會顯示出來,其他所有碎片都會堆積在下面。我從文檔的印象中看到後退按鈕會顛倒上次事務(在提交之前添加的任何內容)。任何人都可以解釋爲什麼這可能導致這種意外的行爲?這是我的主要活動。該片段在activity_main.xml中所有定義:addToBackStack顯示所有片段

public class MainActivity extends MenuBaseActivity { 
    private static final int HOME = 0; 
    private static final int WRITE = 1; 
    private static final int UPLOAD = 2; 
    private static final int SHARE = 3; 
    private static final int SNAP = 4; 
    private static final int POSITION = 5; 

    private static final int FRAGMENT_COUNT = POSITION + 1; 

    /** The current fragment being displayed **/ 
    private int mCurrentFragment = -1; 

    private Fragment[] fragments = new Fragment[FRAGMENT_COUNT]; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_main); 

     FragmentManager fm = getSupportFragmentManager(); 

     fragments[HOME] = fm.findFragmentById(R.id.homeFrag); 
     fragments[WRITE] = fm.findFragmentById(R.id.writeFrag); 
     fragments[UPLOAD] = fm.findFragmentById(R.id.uploadFrag); 
     fragments[SHARE] = fm.findFragmentById(R.id.shareFrag); 
     fragments[SNAP] = fm.findFragmentById(R.id.snapFrag); 
     fragments[POSITION] = fm.findFragmentById(R.id.positionFrag); 

     // If no fragments are currently being displayed, show the home frag 
     if(mCurrentFragment == -1) { 
      showFragment(0,true); 
     } 


    } 

    /* 
    * Handles the click event for all navigation buttons (navOnClick) in the fragments. 
    */ 
    //TODO: Tag navigation with text strings instead of integers 
    public void navOnClick(View v) { 

     Object objectTag = v.getTag(); 
     int tag = Integer.valueOf(objectTag.toString()); 
     showFragment(tag, true); 
    } 


    public void showFragment(int fragmentIndex, boolean addToBackStack) { 

     Log.v(Constants.getLogTag(), "Main: fragmentIndex:" + fragmentIndex + " backstack:" + addToBackStack); 

     FragmentManager fm = getSupportFragmentManager(); 
     FragmentTransaction ft = fm.beginTransaction(); 
     //ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right); 

     for (int i = 0; i < fragments.length; i++) { 
      if (i == fragmentIndex) { 
       ft.show(fragments[i]); 
       } else { 
       ft.hide(fragments[i]); 
      } 
     } 

     if (addToBackStack) { 
      Log.v(Constants.getLogTag(), "Main: Adding to backstack"); 
      ft.addToBackStack(null); 
     } 

     //Update the current fragment identifier 
     mCurrentFragment = fragmentIndex; 

     ft.commit(); 
    } 


} 
+0

您通過您的數組迭代和隱藏每一個片段在一個事務中,所以當你點擊後退按鈕,它取消隱藏所有的人都在一次。 – btse

+0

在那裏似乎很混亂。改變你的整個邏輯,不要這樣做。 –

+1

@ M-WaJeEh也許你可以建議一個快速重構,我不認爲你的評論是非常有幫助的。 – jwBurnside

回答

1

我沒有親自測試了這一點,但讓我知道如何工作的。

我實際上決定保留這個數組,以便我們可以在活動首次啓動時正確隱藏每個片段。我改變了一些應該解決問題的小東西。每次循環都不需要隱藏每個片段。您應該只需要每次隱藏當前片段。

public class MainActivity extends MenuBaseActivity { 
    private static final int HOME = 0; 
    private static final int WRITE = 1; 
    private static final int UPLOAD = 2; 
    private static final int SHARE = 3; 
    private static final int SNAP = 4; 
    private static final int POSITION = 5; 

    /** The current fragment being displayed **/ 
    private int mCurrentFragment = HOME; 

    private Fragment[] fragments = new Fragment[FRAGMENT_COUNT]; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_main); 

     FragmentManager fm = getSupportFragmentManager(); 
     FragmentTransaction ft = fm.beginTransaction(); 

     fragments[HOME] = fm.findFragmentById(R.id.homeFrag); 
     fragments[WRITE] = fm.findFragmentById(R.id.writeFrag); 
     fragments[UPLOAD] = fm.findFragmentById(R.id.uploadFrag); 
     fragments[SHARE] = fm.findFragmentById(R.id.shareFrag); 
     fragments[SNAP] = fm.findFragmentById(R.id.snapFrag); 
     fragments[POSITION] = fm.findFragmentById(R.id.positionFrag); 

     // Hide all of the fragments except for the home fragment 
     for (int i = WRITE; i < fragments.length; i++) { 
      ft.hide(fragments[i]); 
     } 

     ft.commit(); 
    } 

    /* 
    * Handles the click event for all navigation buttons (navOnClick) in the fragments. 
    */ 
    //TODO: Tag navigation with text strings instead of integers 
    public void navOnClick(View v) { 

     Object objectTag = v.getTag(); 
     int tag = Integer.valueOf(objectTag.toString()); 
     showFragment(tag, true); 
    } 


    public void showFragment(int fragmentIndex, boolean addToBackStack) { 

     Log.v(Constants.getLogTag(), "Main: fragmentIndex:" + fragmentIndex + " backstack:" + addToBackStack); 

     FragmentManager fm = getSupportFragmentManager(); 
     FragmentTransaction ft = fm.beginTransaction(); 

     // I changed this part too. You will probably want to implement it this way 
     // if you want to also see an animation when hitting the back button. I will 
     // leave it up to you as an exercise to figure out how the other animator 
     // files should be constructed 
     ft.setCustomAnimations(R.animator.slide_in_right, R.animator.slide_out_left, 
           R.animator.slide_in_left, R.animator.slide_out_right); 

     ft.hide(fragments[mCurrentFragment]); 
     ft.show(fragments[fragmentIndex]); 

     if (addToBackStack) { 
      Log.v(Constants.getLogTag(), "Main: Adding to backstack"); 
      ft.addToBackStack(null); 
     } 

     //Update the current fragment identifier 
     mCurrentFragment = fragmentIndex; 

     ft.commit(); 
    } 
} 
+0

欣賞幫助。雖然你的例子大部分工作,我期望遇到一些頭痛,因爲我也使用一些內置的相機活動和第三方庫。加上片段似乎過度殺傷。將所有內容轉換爲活動並僅在需要更改其他設備的佈局時使用片段。 – jwBurnside

+0

@jwburnside對我來說這聽起來不錯。正如一個附註,我認爲你的應用程序的初始佈局很奇怪。如果您打算將每個片段用作自己的屏幕,則應該將每個片段作爲一個活動進行處理,並以編程方式創建它們,即爲每個片段創建一個單獨的片段類。在xml中對它們全部進行硬編碼,然後隱藏它們都是一種奇怪的方式,它可以防止你在需要時摧毀碎片。只是在將來要記住的東西。 – btse