2014-04-29 106 views
3

的activity_fragment.xml代碼:FragmentManager findFragmentById返回NULL

<?xml version="1.0" encoding="utf-8" ?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/fragmentContainer" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
/> 

CrimeListActivity.java

package com.sinory.criminalintent; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.util.Log; 

public class CrimeListActivity extends SingleFragmentActivity { 

    @Override 
    protected Fragment createFragment() { 
     return new CrimeListFragment(); 
    } 

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

     Log.d("CrimeListActivity", "create"); 
    } 

} 

SingleFragmentActivity.java

的代碼
package com.sinory.criminalintent; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 

public abstract class SingleFragmentActivity extends FragmentActivity { 

    protected abstract Fragment createFragment(); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_fragment); 

     FragmentManager fm = getSupportFragmentManager(); 
     Fragment fragment = fm.findFragmentById(R.id.fragmentContainer); 

     if (null == fragment) { 
      fragment = new CrimeListFragment(); 
      fm.beginTransaction().add(R.id.fragmentContainer, fragment).commit(); 
     } 
    } 
} 

剛開始的代碼學習Android。爲什麼片段fragment = fm.findFragmentById(R.id.fragmentContainer)爲空?請幫幫我。

回答

10

首先,你不需要檢查片段是否爲空,因爲當一個活動銷燬所有的片段時也會被銷燬。所以在活動onCreate中將不會有片段,並且您需要在每次活動重新創建時添加它。
其次不要使用findFragmentById。當你在你的xml文件中定義你的片段時,你只使用這個方法。現在您動態添加片段,您需要指定一個字符串標記,然後使用該標記查找片段。

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_fragment); 

    FragmentManager fm = getSupportFragmentManager(); 
    fm.beginTransaction().add(R.id.fragmentContainer, fragment,"TagName").commit(); 
} 

,如果你需要找到自己的片段只需使用此代碼

Fragment fragment = fm.findFragmentByTag("TagName"); 
+1

「您只能在xml文件中定義片段時使用此方法。」這不完全正確。您可以將fragment添加到activity.xml中的指定ViewGroup中:getFragmentManager() .beginTransaction() .add(R.id.someFrameLayoutForExample,new MainFragment()) .commit();然後檢索它getFragmentManager()。findFragmentById(R.id.someFrameLayoutForExample);這裏的關鍵點和使用findFragmentByTag()是在找到之前必須先添加。不管它將如何完成 - 通過xml或代碼。 – Deepscorn

0

這是好的它是空的。它告訴你片段還沒有創建。這就是爲什麼之後你會創建幾行。

當活動重新啓動/重新創建時,可以調用onCreate方法,在這種情況下,用於存在的碎片將仍然存在,然後引用將不爲空。

+0

當程序啓動時會調用'onCreate',但我編寫代碼'setContentView(R.layout.activity_fragment)'爲什麼它仍然返回null。 – sinory

1

當沒有該ID的片段時,它將爲空。這是正常的流程。但更好的方法是使用findFragmentByTag代替。由於您在創建片段並在管理器上添加/替換片段時將標籤設置爲任何內容,因此很容易通過標籤查找並跟蹤它們。

0

我這樣做的建議,而我仍然得到一個空的返回值。

FragmentManager fragMan = getSupportFragmentManager(); 
     FragmentTransaction fragTran = fragMan.beginTransaction(); 

     ControlsFragment ctrlFrag = new ControlsFragment(); 

     fragTran.add(R.id.fragment_container, ctrlFrag, "ctrl"); 
     fragTran.commit(); // commit additions 

     FragmentManager fm = this.getSupportFragmentManager(); 
     Fragment test = fm.findFragmentByTag("ctrl"); 
     System.out.println(test); 
     Spinner spin1 = (Spinner)test.getView().findViewById(R.id.rythmspinner2); 
    System.out.println(spin1); 
     if (spin1 != null) spin1.setSelection(3); 
0

我添加以下代碼行,其中我打電話findFragmentById並得到一個空值前行吧,給我說,那裏存在片段列表:

List<Fragment> listFrags = getActiveFragments(); 

然後,我通過點擊左側的列添加了一個斷點。然後,我以調試模式運行應用程序。我在調試器中查看listFrags,當我點擊該斷點並在列表中看到了我想要的片段時。我看了以下兩個值:

  • mTag(這是由findFragmentByTag返回)
  • mFragmentId(這是由findFragmentById返回)

通過檢查這個方式,我學到我需要使用findFragmentByTag得到我想要的片段,而不是findFragmentById。我希望這個解決方案和/或這些調試步驟對您中的一個或多個人有幫助。

相關問題