2013-11-26 55 views
0

如果我加入片段到我的活動是這樣的:getSupportFragmentManager()findFragmentByTag不可預知的行爲

fragment_tags = new ArrayList<String>(); 
    fragment_tags.add("user_fragment"); 
    fragment_tags.add("memorial_fragment"); 

    UserFragment user = new UserFragment(); 
    MemorialFragment memorial = new MemorialFragment(); 

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 

    ft.add(R.id.content_frame, user, fragment_tags.get(0)); 
    ft.add(R.id.content_frame, memorial, fragment_tags.get(1)); 
    ft.commit(); 

,然後過一段時間後,我試圖檢索這些片段是這樣的:

List<Fragment> frg = getSupportFragmentManager().getFragments(); 
    Fragment fragUser = getSupportFragmentManager().findFragmentByTag(
      "user_fragment"); 
    Fragment fragUserID = getSupportFragmentManager().findFragmentById(
      R.id.user_fragment_id); 
      Log.d("MV", "fragments size:" + (frg == null ? " null" : frg.size())); 

Log.d將始終返回2的大小,但fragUser有時爲空,有時它是我放入事務的片段。

哪個更有趣的是,這段代碼:

try { 
     Log.d("MV", "0:" + frg.get(0).toString()); 
     Log.d("MV", "1:" + frg.get(1).toString()); 
    } catch (NullPointerException e) { 
     Log.d("MV", "null caught"); 
    } 

有時兩個片段工作,有時僅僅爲第一,如果我這樣做smething這樣的:

if(frg.get(0) == fragUser) 

這將是有時評估爲真實,但並不經常..我不太瞭解這種行爲,但我需要實現多個片段之間的切換,所以我需要獲得對確切片段的引用。任何人?我試圖解決這個問題6個小時,我真的不知道如何做到這一點。謝謝

+0

那麼回答一部分...... **「if(frg.get(0)== fragUser)」** ...你不能使用'=='比較對象。你需要使用'if(frg.get(0))。equals(fragUser))' – Squonk

+0

Squonk實際上這是我的意圖..我不在乎對象是否具有相同的屬性,但如果它們的引用是相同的,它們必須是相同的對象..我想要相同的片段。 – vanomart

回答

0

由於這個問題是我在2013年發佈的,獲得了超過1000次的意見,但仍然沒有任何迴應,我將嘗試總結一下我在處理碎片時所學到的東西。

  1. 不要使用getSupportFragmentManager()。getFragments()(關於這一點在getSupportFragmentManager().getFragments() shows a compile time error
  2. FragmentManager是有管理片段的生命週期。不要試圖將碎片放入自己的列表或保留對它們的強烈參考
  3. if(frg.get(0) == fragUser)不能一致工作的原因與第2點有關。 - FragmentManager管理碎片,因此當它決定殺死碎片時並重新創建它,引用將不匹配。

現在的問題 - 如何安全地使用碎片?使用setArguments

  1. 將數據傳遞給片段束()方法,因此Android可以殺死&重新創建片段。
  2. FragmentManager.findFragmentById(R.id.some_id)將查找附加到id爲some_id的視圖的片段。很有可能如果你有多個片段添加到R.id.some_id中,FragmentManager.findFragmentById(R.id.some_id)會給出不同的結果(但通常是一個非常好的方法來找出哪些片段當前可見,除非你也隱藏/顯示你的片段)
  3. 瞭解FragmentTransaction API的不同方法,特別是addreplace,hide,detach,removeshow之間的差異。
  4. 有時事情並不奏效(當多個片段過渡動畫同時運行時崩潰),或者你的應用程序不是片段的好用例。你可以在現在的經典文章中閱讀更多關於後者的文章https://medium.com/square-corner-blog/advocating-against-android-fragments-81fd0b462c97