2014-04-29 68 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。我希望这个解决方案和/或这些调试步骤对您中的一个或多个人有帮助。

相关问题