java.lang.IllegalArgumentException:找不到用于片段的id 0x1020002(android:id / content)的视图

时间:2014-09-04 12:32:35

标签: android fragmenttransaction

我正试图从一个片段移动到另一个片段。它在片段事务处理期间显示以下错误 -

    java.lang.IllegalArgumentException: No view found for id 0x1020002 (android:id/content) for fragment PhotosFragment2{41a57218 #3 id=0x1020002}
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:930)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115)
            at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1478)
            at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:446)
            at android.os.Handler.handleCallback(Handler.java:615)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:153)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
            at dalvik.system.NativeStart.main(Native Method)

以下是类。我使用了以下代码进行片段事务

Fragment fragment = new PhotosFragment2();

                        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
                        fragmentTransaction.replace(android.R.id.content, fragment);
                        fragmentTransaction.commit();

PhotosFragment.java

   public class PhotosFragment extends Fragment {
        private FragmentActivity myContext;
        @Override
        public void onAttach(Activity activity) {
            myContext = (FragmentActivity) activity;
            super.onAttach(activity);
        }

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

            View rootView = inflater.inflate(R.layout.photos, container, false);

            rootView.setVerticalScrollBarEnabled(false);
            int[] mThumbIds = {
                    R.drawable.album8, R.drawable.album3,
                    R.drawable.album4, R.drawable.album8,
                    R.drawable.album6, R.drawable.album7,
                    R.drawable.album12, R.drawable.album10,
            };

            int[] mThumbIds2 = {
                    R.drawable.album8, R.drawable.album3,
                    R.drawable.album4,
                    R.drawable.album6, R.drawable.album7,
                    R.drawable.album9, R.drawable.album10,
                    R.drawable.album11, R.drawable.album12, R.drawable.album8,
                    R.drawable.album8, R.drawable.album3,
                    R.drawable.album4,
                    R.drawable.album6, R.drawable.album7,
                    R.drawable.album9, R.drawable.album10,
                    R.drawable.album11, R.drawable.album12, R.drawable.album8,
            };

            CustomGridSingle2 adapter = new CustomGridSingle2(myContext, mThumbIds);
            GridView grid = (GridView)rootView.findViewById(R.id.gridView);
            final ImageView img= (ImageView)rootView.findViewById(R.id.imageView7);
            grid.setFocusable(false);

            grid.setAdapter(adapter);
    grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Fragment fragment = new PhotosFragment2();

            FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
            fragmentTransaction.replace(android.R.id.content, fragment);
            fragmentTransaction.commit();
        }
    });
            CustomGridSingle2 adapter2 = new CustomGridSingle2(myContext, mThumbIds2);
            GridView grid2 = (GridView)rootView.findViewById(R.id.gridView2);
            grid2.setFocusable(false);
            grid2.setAdapter(adapter2);
            grid2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Fragment fragment = new PhotosFragment2();

                    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
                    fragmentTransaction.replace(android.R.id.content, fragment);
                    fragmentTransaction.commit();
                }
            });

            return rootView;
        }


    }

PhotosFragment2.java

public class PhotosFragment2 extends Fragment {
    private FragmentActivity myContext;
    @Override
    public void onAttach(Activity activity) {
        myContext = (FragmentActivity) activity;
        super.onAttach(activity);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        View rootView = inflater.inflate(R.layout.photos2, container, false);
        myContext.getActionBar().hide();
        return rootView;
    }
}

活动xml文件

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <LinearLayout
        android:id="@+id/left_drawer_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@drawable/bgmenu"
        android:orientation="vertical">

        <RelativeLayout
            android:id="@+id/profilelayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:paddingTop="10dp">


            <ImageView
                android:id="@+id/drawer_profile_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBottom="@+id/drawer_profile_background"
                android:layout_alignLeft="@+id/drawer_profile_background"
                android:layout_alignRight="@+id/drawer_profile_background"
                android:layout_alignTop="@+id/drawer_profile_background"
                android:layout_marginBottom="7.667dp"
                android:layout_marginLeft="6.5dp"
                android:layout_marginRight="8.3dp"
                android:layout_marginTop="7.667dp"
                android:scaleType="centerCrop"></ImageView>


            <ImageView
                android:id="@+id/drawer_profile_background"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:scaleType="centerCrop"
                android:src="@drawable/profileblock">

            </ImageView>

            <ImageView
                android:id="@+id/settingicon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBottom="@+id/drawer_profile_background"
                android:layout_marginLeft="-15dp"
                android:layout_toRightOf="@+id/drawer_profile_background"
                android:background="@drawable/settings" />

            <textview
                android:id="@+id/username"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/drawer_profile_background"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="5dp"
                android:text="Name"
                android:textAppearance="?android:attr/textAppearanceListItemSmall"
                android:textColor="@android:color/white" />


        </RelativeLayout>


        <ListView
            android:id="@+id/list_slidermenu"
            style="@style/buttonStyle"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_marginTop="30dp"
            android:layout_weight="2"
            android:cacheColorHint="@android:color/transparent"
            android:choiceMode="singleChoice"
            android:divider="@android:color/transparent"
            android:dividerHeight="1dp"
            android:listSelector="@android:color/transparent"
            android:scrollbars="none" />

    </LinearLayout>
</android.support.v4.widget.DrawerLayout>

16 个答案:

答案 0 :(得分:26)

使用fragmentTransaction.replace(R.id.container,fragment)时,它会删除容器中已有的所有碎片,并将新的碎片添加到同一个容器中。

现在我可以为您推荐2件事。首先,如果您想使用现在正在执行的fragmentTransaction.replace(android.R.id.content, fragment);,请不要使用{{1}为您的Activity设置内容这应该可以正常工作。要知道究竟setContentView到底是什么,你可以参考this stackoverflow question and answer

或者其次,在android.R.id.content的布局中,Activity的ID为FrameLayout。然后使用

content

希望这有帮助。

更多信息:

从您的评论中看来,您在fragmentTransaction.replace(R.id.content, fragment); fragmentTransaction.addToBackStack(null);//add the transaction to the back stack so the user can navigate back // Commit the transaction fragmentTransaction.commit(); 的布局中使用FrameLayout时遇到了一些问题(不是Activity& #39; s布局)。从Documents

  

FrameLayout旨在阻挡屏幕上的某个区域以显示单个项目。通常,FrameLayout应该用于保存单个子视图,因为以一种可以扩展到不同屏幕大小而儿童不会相互重叠的方式组织子视图可能很困难。

因此Fragment的主要目的是阻止适合最大子视图所需的区域。如果您使用FrameLayout作为FrameLayout容器,则可以确保始终拥有可用空间以容纳最大Fragment的布局。

因此,您可以在Fragment的布局xml文件中使用FrameLayout这样的内容

Activity

答案 1 :(得分:19)

我不使用getSupportFragmentManager()。 我使用getChildFragmentManager(),它对我有用。 你可以尝试一下。

答案 2 :(得分:14)

如果您尝试将Fragment加入Fragment,请使用getChildFragmentManager()

答案 3 :(得分:6)

如果您使用的是ViewPager,请使用getChildFragmentManager()作为寻呼机适配器

viewPager.setAdapter(new ItemsAdapter(getChildFragmentManager()));

答案 4 :(得分:4)

您必须在活动中设置附加了PhotosFragment的内容视图。

protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.activity_main);

    //...
}

答案 5 :(得分:3)

此问题有两个最常见的原因

  1. 在onCreate()方法的setContentView()中指定错误的布局
  2. 使用嵌套片段并使用getSupportFragmentManager()而不是getChildFragmentManager()
  3. 添加它们时也会发生错误

    希望这会有所帮助

    Summved

答案 6 :(得分:1)

由于 Android 4.2(API 17)嵌套片段变得可用。 见this

要将片段放在其他片段中,请使用getChildFragmentManager()

也可在支持库中找到。

答案 7 :(得分:1)

我知道这已经很晚了。但它可能适用于其他人。

我为每个布局声明了id,如(第3行以下)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"

答案 8 :(得分:0)

将这段代码放在PhotosFragment2 onCreateView方法中:

View rootView = inflater.inflate(R.layout.photos2, null);

而不是:

View rootView = inflater.inflate(R.layout.photos2, container, false);

答案 9 :(得分:0)

在我的情况下,我不得不改变

ViewGroup root = (ViewGroup) inflater.inflate(R.layout.sample,
                container);

ViewGroup root = (ViewGroup) inflater.inflate(R.layout.sample,
                container, false);

答案 10 :(得分:0)

这个答案强调了可能发生的一个愚蠢的错误,即在嵌套片段或将活动转换为片段时出现的错误。

如果您尝试使用fragmentManager替换片段中的片段,但不会使父片段膨胀,则可能会导致问题。

BaseFragment.java OnCreateView中:

if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .replace(R.id.container, new DifferentFragment())
                    .commit();
        }

return super.onCreateView(inflater, container, savedInstanceState);

替换super.onCreateView(inflater, container, savedInstanceState); 为片段充气正确的布局:

        return inflater.inflate(R.layout.base_fragment, container, false);

答案 11 :(得分:0)

问题可能是您在某些片段中添加片段和beginTransaction,例如

getFragmentManager().beginTransaction().replace(android.R.id.content, ImageBrowseFragment.newInstance(bundle),"ImageBrowseFragment")
            .addToBackStack(null).commit();

我只是将getFragmentManager()更改为getActivity().getSupportFragmentManager()

然后一切都很顺利

当您在片段中添加片段使用android.R.id.contentWindow.ID_ANDROID_CONTENT时,我猜它代表片段的根容器而不是活动。因此,更改为getActivity().getSupportFragmentManager()可以解决问题

答案 12 :(得分:0)

我遇到了同样的错误,在尝试了很多事情后,我发现问题出在“id”和“getActivity()。getSupportFragmentManager()”。

在我实施之前我喜欢这些

txt_more.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    getChildFragmentManager()
                            .beginTransaction()
                            .replace(R.id.content_frame, new OpportunitiesFragment())
                            .commit();                }

            });

然后我改为这些

 txt_more.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
    ## Heading ##
                        getActivity().getSupportFragmentManager()
                                .beginTransaction()
                                .replace(android.R.id.content, new OpportunitiesFragment())
                                .commit();                }
                });

答案 13 :(得分:0)

如果将ViewPager与片段(页面)一起使用,并尝试从页面显示新片段 ,则会出现此错误。我认为,您无法从Activity的页面引用ViewPager的容器。

在这种情况下,您应该致电getActivity()。然后在Activity中编写一个将打开新片段的方法。

class YourActivity : AppCompatActivity() {

    fun showNewFragment(title: String) {
        val fm = supportFragmentManager
        fm?.beginTransaction()?.apply {
            val fragment = NewFragment.newInstance(title)
            replace(R.id.container, fragment, NewFragment.TAG)
            addToBackStack(null)
        }?.commit()
    }
}

class PageFragment : Fragment() {

    private fun show() {
        (activity as YourActivity).showNewFragment("New fragment")
    }
}    

如果您调用getParentFragment()并添加一个新片段,那么您将在ViewPager内放置一个新片段:

class ViewPagerFragment : Fragment() {

    fun showNewFragment(title: String) {
        val fm = childFragmentManager
        fm?.beginTransaction()?.apply {
            val fragment = NewFragment.newInstance(title)
            replace(R.id.container, fragment, NewFragment.TAG)
            addToBackStack(null)
        }?.commit()
    }
}

class PageFragment : Fragment() {

    private fun show() {
        (parentFragment as? ViewPagerFragment)?.showNewFragment("New fragment")
    }
}

答案 14 :(得分:0)

确保要调用的片段ID在onCreate方法的setcontent中列出的类中。就我而言,我正在编辑从线性到约束的布局。为了不打乱工作代码,我制作了另一个布局,但在流程中弄乱了一个id,以便oncreate上的内容是经过编辑的布局,但是要调用的片段来自旧布局。显然,在新布局中,我给了它一个不同的id名称。使用ctrl + shift + f搜索片段的ID,并查看搜索结果是否指向您在oncreate方法中指定的布局。祝你好运。

答案 15 :(得分:0)

最常见的错误是,如果您有多个版本的XML布局(例如v21和v23),并且仅在较低版本的XML中添加了<fragment>标签(反之亦然) )。 因此,请检查您是否在两个版本中都添加了<fragment>标记(或pageGroup等)。