调用 onCreateView() 之前出现“找不到片段 id 的视图”错误

Posted

技术标签:

【中文标题】调用 onCreateView() 之前出现“找不到片段 id 的视图”错误【英文标题】:"no view found for id for fragment" error before onCreateView() called 【发布时间】:2012-07-20 06:04:34 【问题描述】:

这与几篇文章有关,但我没有看到任何解释视图层次结构中视图创建顺序的内容(静态 - xml 和动态 - 在代码中)。

我有一个 FragmentActivity 托管一个 Activity 和一个 Fragment。在调用片段的 onCreateView 之前,我从没有为片段创建的视图中收到运行时错误。很难确定调用方法是什么找不到视图,因为调试器在单步执行期间似乎无法找到正确的行号。

我无法正确附加源以查看 FragmentManager 内部,因为 dl'd 源和 .jar 之间似乎不匹配

我在 StreamingActivity.onCreateView 中放置了一个 Log.i 条目,并且在此之前发生了错误。

这里是相关的 LogCat:

07-19 10:13:36.091: I/StreamingActivity(9886): onCreate
07-19 10:13:42.271: W/dalvikvm(9886): threadid=1: thread exiting with uncaught exception (group=0x40020560)
07-19 10:13:42.281: E/androidRuntime(9886): FATAL EXCEPTION: main
07-19 10:13:42.281: E/AndroidRuntime(9886): java.lang.RuntimeException: Unable to start activity   
ComponentInfokesten.fragmentstestbed/kesten.fragmentstestbed.FragmentsMainActivity:        
java.lang.IllegalArgumentException: No view found for id 0x7f05002e for fragment 
StreamingActivity4052f810 #0 id=0x7f05002e
caused by
java.lang.IllegalArgumentException: No view found for id 0x7f05002e for fragment 
StreamingActivity40530948 #0 id=0x7f05002e
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:865)

我的java文件sn-ps:

public class FragmentsMainActivity extends FragmentActivity 

public final static int STARTUP_ACTIVITY_RESULT=0;

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

    if(savedInstanceState == null) 
        Intent intentStartupActivity = new Intent(this, StartupActivity.class);
        if(intentStartupActivity != null)
            startActivityForResult(intentStartupActivity, STARTUP_ACTIVITY_RESULT);

        // get an instance of FragmentTransaction from your Activity
        FragmentTransaction fragmentTransaction = 
                getSupportFragmentManager().beginTransaction();

        //add a fragment
        StreamingActivity streamingActivity = new StreamingActivity();
        if (streamingActivity != null) 
            fragmentTransaction.add(R.id.streamingactivity, streamingActivity);
            fragmentTransaction.commit();
        
    

我的片段:

public class StreamingActivity extends Fragment 

public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    Log.i("StreamingActivity","onCreate")   

我的布局文件: "res/layout/main.xml"

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    >

    <FrameLayout
    android:id="@+id/streamingactivity"
    android:layout_
    android:layout_>
</FrameLayout>


<!-- IMU -->
<TextView
    android:id="@+id/imu_label"
    style="@style/Label.Title"
    android:text="@string/imu"
    />

<kesten.fragmentstestbed.ImuView
    android:id="@+id/imu_values"
    android:layout_
    android:layout_
    android:layout_below="@+id/imu_label"
    android:text=""
    />

<!-- Accelerometer -->
<TextView
    android:id="@+id/accelerometer_label"
    style="@style/Label.Title"
    android:text="@string/accelerometer"
    android:layout_below="@+id/imu_values"
    />

<!-- Filtered -->
<kesten.fragmentstestbed.CoordinateView
    android:id="@+id/accelerometer_filtered_coordinates"
    android:layout_
    android:layout_
    android:layout_below="@+id/accelerometer_label"
    android:text="@string/filtered"
    />

</RelativeLayout>

和我的 FragmentActivity 的“activity_fragments_main.xml”

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_ >

    <TextView
        android:layout_
        android:layout_
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="@string/hello_world"
        tools:context=".FragmentsMainActivity" />

</RelativeLayout>

从其他 *** 线程收集的 id not found 错误的可能原因:

FragmentActivity 的 onCreate() 方法的 setContentView() 布局错误。

我检查了一下,我的 xml 文件都在那里。也许存在语法错误或缺少链接资源,但我看不到它。我知道 HierarchyViewer 将是调试 UI 的有用工具,但我无法让它工作。

传递给 FragmentTransaction.add 的 id 必须是 setContentView 中指定布局的子级。

我的 FragmentActivity 的 onCreate @覆盖 公共无效 onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragments_main);

我的 Fragment 的 onCreateView

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 

    Log.i("StreamingActivity","onCreateView");      
    View view = inflater.inflate(R.layout.main, container, false);

我假设 LayoutManager 为容器传递了正确的值,即在 FragmentActivity 的 setContentView() 中设置的值。但无论如何,我们永远无法到达那里。 logCat中的错误发生在我们进入onCreateView()之前。

我唯一能想到的 atm 是在 setContentView 之后和 StreamingActivity 之前调用的 startupActivity(它是封闭的第三方)将内容视图设置为 R.layout.activity_fragments_main 之外的东西,它不是我的片段视图的父级。

问题似乎源于这样一个事实,即虽然 Activity 有 setContentView 可以随时调用,但 Fragment 只有 onCreateView() 会在启动片段的片段事务之后调用。

在调用 onCreateView() 之前尝试访问片段视图的原因和原因是什么?

达科拉姆

【问题讨论】:

【参考方案1】:

activty_fragments_main 中的TextView 没有id。我遇到了类似的错误,并添加了一个 id,突然间一切都开始工作了......

【讨论】:

【参考方案2】:

以下FrameLayout 应该在activty_fragments_main

   <FrameLayout
    android:id="@+id/streamingactivity"
    android:layout_
    android:layout_>
</FrameLayout>

以下函数在第一个参数中提供的布局内添加一个片段:

 fragmentTransaction.add(R.id.streamingactivity, streamingActivity);

所以尝试改变:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_ >

    <TextView
        android:layout_
        android:layout_
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="@string/hello_world"
        tools:context=".FragmentsMainActivity" />

</RelativeLayout>

到:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_ >


   <FrameLayout
    android:id="@+id/streamingactivity"
    android:layout_
    android:layout_>
</FrameLayout>

</RelativeLayout>

【讨论】:

【参考方案3】:

FragmentMainActivity 中,您将片段添加到 id streamingactivity

fragmentTransaction.add(R.id.streamingactivity, streamingActivity);

和我的 FragmentMainActivity 的“activity_fragments_main.xml”

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_ >

    <TextView
        android:layout_
        android:layout_
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="@string/hello_world"
        tools:context=".FragmentsMainActivity" />

</RelativeLayout>

//你的布局必须包含一个ID为streamingactivity的FrameLayout。你的Activity必须包含

<FrameLayout 
android:id="@+id/streamingactivity"
....
..>

你的StreamingActivityFragment 必须导入android.support.v4.Fragment。并且必须实现onCreateView

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState)     
    return inflater.inflate(R.layout.main, container, false);

或者另一个问题可能是。你已经交换了 Fragment 和 Activity 的 LayoutId。就像你的名字一样

【讨论】:

以上是关于调用 onCreateView() 之前出现“找不到片段 id 的视图”错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们可以在 onActivityCreated 之前运行的 onCreateView 中调用 getActivity()?

在活动的 onCreate 之前调用 Fragment 的 onCreateView

完成 onCreate 中的活动时,如何在 onCreate 之前调用我的片段的 onCreateView?

从`onCreateView`调用`getActivity()`是不是安全?

为啥显示Fragment1之前会调用Fragment2的onCreateView

多次调用片段 onCreateView