Android Fragment没有找到ID的视图?

时间:2011-09-21 23:53:20

标签: android android-fragments illegalargumentexception

我正在尝试添加到视图中的片段。

FragmentManager fragMgr=getSupportFragmentManager();
feed_parser_activity content = (feed_parser_activity)fragMgr
                                    .findFragmentById(R.id.feedContentContainer);
FragmentTransaction xaction=fragMgr.beginTransaction();

if (content == null || content.isRemoving()) {
    content=new feed_parser_activity(item.getLink().toString());
    xaction
        .add(R.id.feedContentContainer, content)
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
        .addToBackStack(null)
        .commit();
    Log.e("Abstract", "DONE");
}

执行此代码时,我在调试中遇到以下错误。

java.lang.IllegalArgumentException: No view found for id 0x7f080011 
   for fragment feed_parser_activity{41882f50 #2 id=0x7f080011}

feed_parser_activity是一个片段,在xml中设置为Fragment layout 我正在使用FragmentActivity来托管保存feed_parser_layout的片段布局 我上面是否正确编码?

39 个答案:

答案 0 :(得分:327)

我也遇到了这个问题,直到我意识到我在FragmentActivity的setContentView()方法的onCreate()中指定了错误的布局。

传入FragmentTransaction.add()的ID(在您的情况下为R.id.feedContentContainer)必须是setContentView()中指定的布局的子级。

您没有向我们展示您的onCreate()方法,因此这可能是同样的问题。

答案 1 :(得分:233)

使用嵌套片段并使用getSupportFragmentManager()而不是getChildFragmentManager()添加它们时也会发生此错误。

答案 2 :(得分:56)

解决方案是使用getChildFragmentManager()

而不是getFragmentManager()

从片段调用时。如果您从某个活动调用该方法,请使用getFragmentManager()

这将解决问题。

答案 3 :(得分:28)

我遇到了这个问题(在代码中构建我的UI时),这是由我的ViewPager(显示Fragment s)没有设置ID引起的,所以我只使用了{{1}然后它起作用。

This page帮我解决了这个问题。

答案 4 :(得分:25)

我见过的另一个场景。 如果您使用嵌套片段,请说片段中的ViewPager,其页面也是片段。

当您在内部片段(ViewPager的页面)中执行Fragment事务时,您将需要

FragmentManager fragmentManager = getActivity().getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

getActivity()是这里的关键。 ...

答案 5 :(得分:12)

我在另一个类似于这个问题的线程上读到的答案,当我遇到这个问题时,这个问题涉及布局xml。

您的logcat显示“找不到ID为0x7f080011的视图”。

打开gen->package->R.java->id,然后查找ID 0x7f080011

当我遇到此问题时,此ID属于FrameLayout文件中的activity_main.xml

FrameLayout没有ID(没有声明android:id = "blablabla")。

确保所有布局中的所有组件都具有ID,尤其是logcat中引用的组件。

答案 6 :(得分:11)

如果您传递给FragmentTransaction.replace(int ID, fragment)的布局ID存在于其他正在膨胀的布局中,也会发生此异常。确保布局ID是唯一的,它应该可以工作。

答案 7 :(得分:11)

com.android.support:support-v4:21.0.0升级到com.android.support:support-v4:22.1.1时出现此错误。

我不得不改变我的布局:

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

对此:

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

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

</FrameLayout> 

所以布局必须有一个子视图。我假设他们在新库中强制执行此操作。

答案 8 :(得分:9)

在我的情况下,我试图显示一个包含寻呼机的DialogFragment,当FragmentPagerAdapter尝试将碎片添加到寻呼机时,抛出了这个异常。根据howettl的回答,我猜这是由于Pager父节点不是我的FragmentActivity中setContentView()中的视图集。

我为解决这个问题所做的唯一改变是创建FragmentPagerAdapter,传入一个通过调用getChildFragmentManager()获得的FragmentMager,而不是像往常那样通过调用getFragmentManager()获得的那个。

    public class PagerDialog extends DialogFragment{

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

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

        MyPagerAdapter pagerAdapter = new MyPagerAdapter(getChildFragmentManager());
        ViewPager pager = (ViewPager) rootView.findViewById(R.id.pager);
        pager.setAdapter(pagerAdapter);

        return rootView;
    }
}

答案 9 :(得分:7)

我知道这已经在一个场景中得到了解答,但我的问题略有不同,我想我会分享以防其他任何人在我的鞋子里。

我在onCreate()内进行了一次交易,但此时视图树还没有被充气,所以你得到同样的错误。将事务代码放在onResume()中使一切运行正常。

因此,请确保在视图树膨胀后运行您的事务代码!

答案 10 :(得分:7)

我有同样的问题,但我的问题是在方向改变时发生的。其他解决方案都没有奏效。因此,当根据屏幕尺寸进行两个或一个窗格布局时,我忘记从我的片段中删除setRetainInstance(true);

答案 11 :(得分:6)

在Recycler View中使用Viewpager时,我遇到了一个令人讨厌的错误。 我在特殊情况下面临的错误。 我创建了一个带有Viewpager的RecyclerView的片段(使用FragmentStatePagerAdapter)。它运行良好,直到我在RecyclerView中单击一个Cell切换到不同的片段,然后使用Phone的硬件Back按钮导航回来,App崩溃。

有趣的是,我在同一个RecyclerView中有两个Viewpage,两个距离大约5个单元(其他在屏幕上看不到,它已经关闭)。所以最初我只是将解决方案应用到第一个Viewpager并保留其他原样(Viewpager使用Fragments)。

当第一个查看寻呼机可见时,导航后工作正常。现在,当我向下滚动到第二个然后更改片段并返回时,它崩溃了(同样的事情发生在第一个)。所以我不得不改变两个Viewpage。

无论如何,请阅读以下内容以找到有效的解决方案。 下面的崩溃错误:

java.lang.IllegalArgumentException: No view found for id 0x7f0c0098 (com.kk:id/pagerDetailAndTips) for fragment ProductDetailsAndTipsFragment{189bcbce #0 id=0x7f0c0098}

花了几个小时调试它。阅读完整的主题帖子,直到底部应用所有解决方案,包括确保我传递childFragmentManager。

没有任何效果。

最后,我没有使用FragmentStatePagerAdapter,而是扩展了PagerAdapter并在Viewpager中使用它而不使用片段。我相信一些有嵌套片段的BUG。无论如何,我们有选择。阅读...

以下链接非常有用:

Viewpager Without Fragments

链接可能会死亡,所以我在下面发布我实施的解决方案:

public class ScreenSlidePagerAdapter extends PagerAdapter {
private static final String TAG = "ScreenSlidePager";
ProductDetails productDetails;
ImageView imgProductImage;
ArrayList<Imagelist> imagelists;
Context mContext;

// Constructor
public ScreenSlidePagerAdapter(Context mContext,ProductDetails productDetails) {
    //super(fm);
    this.mContext = mContext;
    this.productDetails = productDetails;
}

// Here is where you inflate your View and instantiate each View and set their values
@Override
public Object instantiateItem(ViewGroup container, int position) {
    LayoutInflater inflater = LayoutInflater.from(mContext);
    ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.product_image_slide_cell,container,false);

    imgProductImage = (ImageView) layout.findViewById(R.id.imgSlidingProductImage);
    String url = null;
    if (imagelists != null) {
        url = imagelists.get(position).getImage();
    }

    // This is UniversalImageLoader Image downloader method to download and set Image onto Imageview
    ImageLoader.getInstance().displayImage(url, imgProductImage, Kk.options);

    // Finally add view to Viewgroup. Same as where we return our fragment in FragmentStatePagerAdapter
    container.addView(layout);
    return layout;
}

// Write as it is. I don't know much about it
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView((View) object);
    /*super.destroyItem(container, position, object);*/
}

// Get the count
@Override
public int getCount() {
    int size = 0;

    if (productDetails != null) {
        imagelists =  productDetails.getImagelist();
        if (imagelists != null) {
            size = imagelists.size();
        }
    }
    Log.d(TAG,"Adapter Size = "+size);
    return size;
}

// Write as it is. I don't know much about it
@Override
public boolean isViewFromObject(View view, Object object) {

    return view == object;
}

}

希望这有用!!

答案 12 :(得分:5)

使用嵌套片段

使用getChildFragmentManager()代替getActivity.getSupportFragmentManager()已解决崩溃java.lang.IllegalArgumentException:找不到我的ID视图。

答案 13 :(得分:5)

我的错误在于FragamentTransaction

我这样做t.replace(R.layout.mylayout);而不是t.replace(R.id.mylayout);

区别在于一个是布局,另一个是layout(id)

的引用

答案 14 :(得分:4)

以防万一有人犯了我犯的同样愚蠢的错误;检查您是否没有在某处覆盖活动内容(即寻找对setContentView的其他调用)

在我的情况下,由于不小心进行复制和粘贴,我在片段中使用了DataBindingUtil.setContentView而不是DataBindingUtil.inflate,它弄乱了活动的状态。

答案 15 :(得分:3)

此页面似乎是发布有关Fragment IllegalArgumentException的建议的良好中心位置。这是你可以尝试的另外一件事。这最终对我有用:

我忘记了我有一个单独的横向布局文件。我在那里添加了我的FrameLayout容器之后,片段也工作了。


另外请注意,如果您已经尝试过此页面上建议的所有其他内容(以及整个互联网)并且已经将您的头发拉了几个小时,请考虑将这些烦人的碎片倾倒并回到原来的旧位置标准布局。 (当我终于发现问题时,这实际上就是我在做的事情。)你仍然可以使用容器概念。但是,您可以使用xml include标记将其填充为您在片段中使用的相同布局,而不是使用片段填充它。您可以在主布局中执行以下操作:

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

    <include layout="@layout/former_fragment_layout" />

</FrameLayout>

其中former_fragment_layout是您尝试在片段中使用的xml布局文件的名称。有关详细信息,请参阅Re-using Layouts with include

答案 16 :(得分:3)

我有同样的问题,让我发布我的代码,以便你们都可以看到它,而不是做我做的那样。

@Override
protected void onResume()
{
    super.onResume();

    fragManager = getSupportFragmentManager();

    Fragment answerPad=getDefaultAnswerPad();
    setAnswerPad(answerPad);
    setContentView(R.layout.abstract_test_view);
}
protected void setAnswerPad(AbstractAnswerFragment pad)
{
    fragManager.beginTransaction()
        .add(R.id.AnswerArea, pad, "AnswerArea")
        .commit();
    fragManager.executePendingTransactions();
}

请注意,我在setContentView之前设置了片段。糟糕!

答案 17 :(得分:2)

在我的情况下,我在Recycler视图项中有一个SupportMapFragment(我使用较低的开销&#34; liteMode&#34;这使得地图显示为非交互式,几乎像静态图像)。我正在使用正确的FragmentManager,一切似乎工作正常...有一个小列表。一旦项目列表超过屏幕高度,我就会在滚动时开始出现此问题。

原来,这是因为我在一个视图中注入了一个动态的SupportMapFragment,它位于另一个片段中,以解决我在尝试在XML中静态声明它时遇到的一些问题。因此,一旦视图附加到窗口,即在屏幕上可见,片段占位符布局只能用实际片段替换。所以我把我的代码用于初始化SupportMapFragment,执行Fragment替换,并在onAttachedToWindow事件中调用getMapAsync()。

我忘记做的是确保我的代码没有运行两次。即在onAttachedToWindow事件中,检查我的动态SupportMapFragment在尝试创建它的新实例并执行Fragment替换之前是否仍为null。当项目离开RecyclerView的顶部时,它会从窗口中分离,然后在您向后滚动时重新附加,因此会多次触发此事件。

一旦我添加了空检查,每个RecyclerView项目只发生一次,问题就消失了! TL;!DR

答案 18 :(得分:1)

当您从另一个片段中调用片段时会发生这种情况。

使用:

getActivity().getSupportFragmentManager().beginTransaction();

答案 19 :(得分:1)

在我的情况下,当我为同一个布局元素(片段占位符)使用不同的id时,抛出了这个异常,同时为不同的Build Variants使用了几个。出于某种原因,当你第一次更换片段时,它的效果非常好,但是如果你再试一次,你会得到这个例外。 因此,如果您有不同的Build Variants布局,请确保使用相同的ID。

答案 20 :(得分:1)

我修复了这个错误,我使用commitNow()替换commit()

mFragment.getChildFragmentManager()
  .beginTransaction()
  .replace(R.id.main_fragment_container,fragment)
  .commitNowAllowingStateLoss();

commitNow是同步方法,commit()方法是异步方法。

答案 21 :(得分:1)

当我尝试用onCreateView()中的片段替换视图时,我遇到了这个问题。像这样:

public class MyProjectListFrag extends Fragment {


    private MyProjectListFragment myProjectListFragment;

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

        FragmentManager mFragmentManager = getFragmentManager();
        myProjectListFragment = new MyProjectListFragment();
        mFragmentManager
                .beginTransaction()
                .replace(R.id.container_for_my_pro_list,
                        myProjectListFragment, "myProjectListFragment")
                .commit();
    }

它告诉我

11-25 14:06:04.848: E/AndroidRuntime(26040): java.lang.IllegalArgumentException: No view found for id 0x7f05003f (com.example.myays:id/container_for_my_pro_list) for fragment MyProjectListFragment{41692f40 #2 id=0x7f05003f myProjectListFragment}

然后我通过将replace放入onActivityCreated()来修复此问题。像这样:

public class MyProjectListFrag extends Fragment {

    private final static String TAG = "lch";

    private MyProjectListFragment myProjectListFragment;

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

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

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);

        FragmentManager mFragmentManager = getFragmentManager();
        myProjectListFragment = new MyProjectListFragment();
        mFragmentManager
                .beginTransaction()
                .replace(R.id.container_for_my_pro_list,
                        myProjectListFragment, "myProjectListFragment")
                .commit();

    }
  1. 您必须在onCreateView()中返回一个视图,以便以后可以替换它
  2. 您可以在片段提升周期的以下功能中对此视图进行任何操作,例如onActivityCreated()
  3. 希望这有帮助!

答案 22 :(得分:0)

有时是因为您使用的是BottomNavigationView。如果您从导航中打开一个Intent,然后在该活动中打开一个片段,请说

transaction.replace(R.id.container,new YourFragment());

然后,活动将无法找到您正在使用的导航方法。

解决方案:将活动更改为分段,并使用应用程序中的addOnBackStack处理导航。如果您已经实现了Jetpack导航,则只需在项目中使用片段即可。

答案 23 :(得分:0)

只需添加viewPager.setOffscreenPageLimit(页数);

答案 24 :(得分:0)

正如https://stackoverflow.com/users/2075875/malachiasz

所说

这个解决方案确实有效

getChildFragmentManager().beginTransaction().replace(R.id.cpu_bottomNav_frame,new fragment()).commit();

答案 25 :(得分:0)

在我的例子中,我在我的活动类中使用了一个通用片段持有者,我在运行时用适当的片段替换了这个通用片段。

问题是我同时为 include 和 generic_fragment_layout 提供了 id,从 include 中删除 id 解决了它。

答案 26 :(得分:0)

有点晚了,但可能会帮助某人:

我是压倒性的 onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) (自动完成首先建议了这个,我在这里添加了 setContentView())

请确保改写正确的: onCreate(savedInstanceState: Bundle?)

答案 27 :(得分:0)

我在我的项目中使用了 View Binding,并且在膨胀 setContentView() 类后不注意添加 ActivityHelloWorldBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityHelloWorldBinding.inflate(layoutInflater)

    // Add this line.
    setContentView(binding.root)
}

答案 28 :(得分:0)

使用childFragmentManager代替活动!! supportFragmentManager

答案 29 :(得分:0)

在我们的情况下,我们已清除/损坏了class.dex文件以及gradle编译的输出。由于没有尝试重新缓存,因此没有错误,但是apk没有所需的文件,导致此令人困惑的错误。 Gradle重新同步和全新的构建使我们摆脱了所有错误。

//快乐编码

答案 30 :(得分:0)

对于navigation library,如果NavHostFragment没有ID,就可能出现此问题。

错误的声明:

<fragment               
     android:name="androidx.navigation.fragment.NavHostFragment"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     app:navGraph="@navigation/myGraph"/>

权利声明:

<fragment
     android:id="@+id/myId"               
     android:name="androidx.navigation.fragment.NavHostFragment"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     app:navGraph="@navigation/myGraph"/>

答案 31 :(得分:0)

就我而言。我有一个Activity和服务器Fragment 一段时间,我需要重新创建Fragment

  • 语言正在改变
  • 片段布局有些不需要,或者内容更改需要重新创建
  • 其他更改
  • 我在活动中清除了所有Fragment并将其全部设置为null 但是Fragment已经创建了自己,同时承载了活动性 是bean设置为null,因此在调用Fragment视图之前 将其检查为空

    例如

    Activity{
        fragment
        recreate{
           fragment = null then new instance
        }
    
    }
    
    Fragment{
        if((activity).fragment != null) {
           findViewById()
        }
    
    }
    

    答案 32 :(得分:0)

    就我而言,我使用片段类文件来声明listview适配器类。 我刚刚为公共适配器类使用了不同的文件,错误消失了。

    答案 33 :(得分:0)

    我遇到了同样的问题,因为我试图在将容器布局添加到活动之前添加片段。

    答案 34 :(得分:0)

    当您在两个具有相同ID的片段中拥有两个视图时,也会发生这种情况

    答案 35 :(得分:0)

    当您没有将<include layout="@layout/your_fragment_layout"/>放入app_bar_main.xml时也会发生此问题

    答案 36 :(得分: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);
    

    答案 37 :(得分:0)

    在创建活动时进行片段交易时,我遇到了同样的问题。

    核心问题是Nick has already pointed out - 视图树尚未膨胀。但他的解决方案并没有起作用 - 在onResume,onPostCreate等中也有同样的例外。

    解决方案是添加回调容器片段,以便在准备就绪时发出信号:

    public class MyContainerFragment extends Fragment {
        public static interface Callbacks {
            void onMyContainerAttached();
        }
    
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            Log.d(TAG, "--- onAttach");
            ((Callbacks) activity).onMyContainerAttached();
        }
    
        //... rest of code
    }
    

    然后在活动中:

    public class MainActivity extends Activity
            implements MyContainerFragment.Callbacks
    {
        @Override
        public void onMyContainerAttached() {
            getFragmentManager()
                    .beginTransaction()
                    .replace(R.id.containerFrame, new MyFragment())
                    .commit();
        }
    
        //...
    }
    

    答案 38 :(得分:-1)

    然后我也遇到了同样的错误,我意识到问题出在.add(R.id.CONTAINERNAME)上,所以基本上我在错误的xml中给出了id = CONTAINERNAME。 因此,解决方案是首先检查您是否在要显示片段的xml中指定了id = CONTAINERNAME。 另请注意,我试图将片段形式称为活动。 我希望这样的小错误能够解决问题

    基于2020年最新版雄激素的参考