Android片段找不到ID的视图?


287

我有一个片段想添加到视图中。

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布局的Fragment。
我正在使用FragmentActivity托管持有的Fragment Layout feed_parser_layout
我在上面正确编码吗?


3
您可以包含XML吗?
jsmith

1
在进行Activity中的setContentView之前进行片段事务处理时,可能会遇到相同的错误
Pavel,

Answers:


373

我是有这个问题太,直到我意识到我已经在指定的错误布局setContentView()中的onCreate()的FragmentActivity的方法。

根据FragmentTransaction.add()您的情况R.id.feedContentContainer,传入的ID 必须是中指定的布局的子级setContentView()

您没有向我们展示您的onCreate()方法,所以也许这是同样的问题。


5
在setContentView中指定的布局子元素是什么意思?如何使它成为孩子?
NinjaCoder

11
如果在XML的父视图中声明了一个视图,则该视图是另一个视图的子视图。即。a的TextView内部RelativeLayout是的子项RelativeLayout
howettl

@howettl:我知道这是旧的帖子。但我无法用您的答案解决此问题。这是一个问题:stackoverflow.com/questions/25844394/…-您能帮我吗?谢谢!
TheDevMan 2014年

@howettl,能否请您帮我解决类似问题。stackoverflow.com/questions/26966623/...
Vamsi Challa

3
发生在我身上。CTRL + C CTRL + V的缺点。
0nyx

294

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


10
我的情况恰恰相反。试图通过调用getChildFragmentManager()添加到主片段容器。指出这一点对我来说解决了。感谢+1
speedynomads 2013年

@Malachiasz:您能否看一下有关ViewPager的问题?谢谢stackoverflow.com/questions/27937250/...
安和武

这正是我的问题,谢谢。奇怪的是,这仅在调用.show()时横向发生。用它替换主要片段效果很好。
cohenadair

1
那正是我的问题,非常感谢!它仅在某些速度较慢的设备上发生,因此很难确切了解正在发生的事情。
YawaraNes

1
多次提出这个问题后,我感到没有其他人遇到我的问题,只需要向下滚动一下即可。如果他们可以得到更具体的错误代码以说可能是这种情况,那将是很好的。
KodyVanRy

67

解决方案是使用 getChildFragmentManager()

代替 getFragmentManager()

从片段调用时。如果要从活动中调用方法,请使用getFragmentManager()

这样可以解决问题。


4
@ surfer190使用getSupportFragmentManager()代替。
阿米尔·侯赛因·加塞米

更改为getChildFragmentManager(),这有效!
Shyam

在我的情况下,我使用的是底部页面片段中使用viewpager的片段导航。您的解决方案非常出色!!Thanx兄弟吨。
Debasish Ghosh

1
有同样的问题,这为我解决了!getChildFragmentManager()而不是getActivity()。getFragmentManager(),一旦我想到它,它就很有意义了:) TY!
西蒙

我正在从一个活动中调用该方法,但是getFragmentManager()现在不推荐使用!
Alireza Noorali

29

我遇到了这个问题(在代码中构建UI时),这是由于我ViewPager(显示Fragments)没有设置ID引起的,所以我简单地使用了pager.setID(id)它,然后就起作用了。

该页面帮助我弄清楚了这一点。


1
使用viewPager时,我遇到了同样的问题。在执行事务之前,使用viewPager.setCurrentItem(n)修复了相同的错误。也许对某人有用。
Kirk Hammett 2014年

就我而言,方向相似,但问题是我在.setID中使用了负值。使用正整数可以解决此问题。
伊格纳西奥(Ignacio Hagopian)

29

我遇到的另一种情况。如果您使用嵌套片段,请在片段中说一个ViewPager,它的页面也就是片段。

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

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

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


是的...对我来说,除此以外,其他所有实现都很好。我直接尝试访问如下代码:FragmentTransaction transaction = getSupportFragmentManager()。beginTransaction(); 然后,像您提到的那样,我分别使用getActivity()得到fragmentmanager。它的效果很好
anand krish

18

以我为例,我试图显示一个包含寻呼机的DialogFragment,当FragmentPagerAdapter尝试将Fragments添加到寻呼机时,抛出此异常。基于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;
    }
}

无法从DialogFragment访问getChildFragmentManager()
Abdalrahman Shatou

13

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


如果ID 不是唯一的,则编译器不会报告ID是否在当前布局中丢失,因此,真正的问题不是ID的唯一性,而是当前布局中ID的遗漏。
塞缪尔

13

当我遇到有关布局xml的问题时,我在与该线程相似的另一线程上读取了一个答案。

您的日志猫说“找不到ID为0x7f080011的视图”。

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

当我遇到此问题时,此ID属于FrameLayoutactivity_main.xml文件中的一个。

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

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


1
真好 在带有LinuxOS的Android Studio中,它位于:/ home / bob / AndroidStudioWorkspace / HelloWorld / app / build / generation / source / r / release / android / support / v7 / appcompat。
portsample'3

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> 

因此,布局必须具有子视图。我假设他们在新库中实施了此操作。


9

带有嵌套片段

对我而言,通过使用getChildFragmentManager()而不是getActivity().getSupportFragmentManager()解决崩溃

java.lang.IllegalArgumentException:找不到ID的视图


但适配器内部无法插入getchildFragmentManger为什么
Sunil Chaudhary

8

我知道在一种情况下已经可以解决此问题,但是我的问题略有不同,我想我愿意和别人分享我的情况。

我在中进行交易onCreate(),但此时视图树尚未膨胀,因此您会遇到同样的错误。放入事务代码可以onResume()使一切正常运行。

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


3
嗯...就我而言,无论这些代码在onCreate还是onResume中都没有影响
IgorGanapolsky

在我的案例中,@ IgorGanapolsky也通过fragment's的回调解决了这一问题onAttach。看到我的答案
Alexander Malakhov 2015年

这正是我的问题。调用另一个类以刷新视图状态的操作是在尚未膨胀的布局上执行片段事务。在onResume()中调用它可以解决此问题。
AWT

8

在Recycler View中使用Viewpager时,我遇到了一个讨厌的错误。在特殊情况下,我遇到的错误低于此。我开始了一个片段,该片段具有一个带有Viewpager的RecyclerView(使用FragmentStatePagerAdapter)。它运行良好,直到我单击RecyclerView中的某个Cell切换到其他片段,然后使用Phone的硬件“后退”按钮导航回去,并且App崩溃了。

有趣的是,我在同一个RecyclerView中有两个Viewpagers,它们都相距约5个像元(其他在屏幕上不可见,它掉了)。因此,最初,我只是将解决方案应用于第一个Viewpager,而其余的都保持不变(使用片段的Viewpager)。

当第一个视图寻呼机可见时,向后导航可以正常工作。现在,当我向下滚动到第二个,然后更改片段并返回时,它崩溃了(第一个发生了同样的事情)。因此,我必须同时更改两个Viewpagers。

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

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

花了几个小时调试它。阅读此完整的Thread帖子,直到应用所有解决方案(包括确保我通过childFragmentManager),从头开始。

没事。

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

以下链接非常有帮助:

没有片段的Viewpager

链接可能会消失,因此我将在此处发布实施的解决方案:

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;
}

}

希望这对您有所帮助!


是的,此解决方案有效,但是如果我需要使用自己的生命周期和变量(而不只是视图)进行困难的构造怎么办?它将与带有播放和静音按钮的videoViews和imageViews一起使用。对我的情况没有帮助吗?
Nikita Axyonov'7


7

我遇到了同样的问题,但是我的问题发生在方向改变上。其他解决方案均无效。因此事实证明setRetainInstance(true);,当基于屏幕大小进行两个或一个窗格布局时,我忘记从片段中删除。


如果您位于嵌套片段中,则将setRetainInstance(true)设置为false,这将修复错误。
ralphgabb14年

5

我的错误在上FragamentTransaction

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

区别在于,一个是布局,另一个是对布局的引用 layout(id)


4

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

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


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。哎呀


1
谢谢!我在做同样的事情,所以我把自己setContentView放进了onBuildHeaders
兰迪(Randy)

3

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

我忘记了我有一个单独的布局文件以显示横向。我也在那里添加了FrameLayout容器后,该片段起作用了。


另外,如果您已经尝试过此页面上建议的所有其他内容(以及整个Internet),并且已经花了数小时的时间,请考虑只丢弃这些令人讨厌的片段,并返回到旧的标准布局。(实际上,这就是我终于发现问题时正在做的事情。)您仍然可以使用容器概念。但是,除了使用片段填充之外,还可以使用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布局文件的名称。有关更多信息,请参见与include一起使用布局


这是一个很好的建议,但是如果需要动态切换片段,则此方法无效。另外,它还降低了可重用性,因为您可以将行为(代码)封装在片段中。
亚历山大·马拉霍夫

我绝对同意。碎片要好得多。
Suragch'3

2

在我的情况下,我在回收站视图项中有一个SupportMapFragment(我使用的是开销较低的“ liteMode”,这使地图看起来像是非交互式的,几乎像静态图像一样)。我使用的是正确的FragmentManager,并且一切似乎都可以正常工作。一旦项目列表超过了屏幕高度,然后滚动时便开始出现此问题。

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

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

添加空检查后,每个RecyclerView项目仅发生一次,并且问题消失了!TL; DR!


2

当您从另一个内部的一个片段调用时,会发生这种情况。

采用 :

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

1

当我尝试用中的片段替换view时遇到了这个问题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()

希望这可以帮助!


1

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

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

commitNow是一种同步的方法,该commit()方法是一种异步方法。


1

在我的情况下,当我为同一布局元素(片段占位符)使用不同的ID,同时为不同的Build Variants使用多个ID时,抛出此异常。由于某种原因,当您第一次替换片段时,它工作得很好,但是如果您再次尝试执行此操作,则会遇到此异常。因此,如果您针对不同的构建变体有多种布局,请确保使用相同的ID。


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);

0

在创建活动时执行片段事务时,我遇到了同样的问题。

核心问题是尼克已经指出的 -视图树尚未膨胀。但是他的解决方案不起作用-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();
    }

    //...
}

0

就我而言,我正在使用一个片段类文件来声明一个listview适配器类。我只是为公共适配器类使用了一个不同的文件,该错误消失了。




0

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


0

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

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

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

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


0

就我而言。我Activity与serveral Fragment有一段时间,需要重新创建Fragments

  • 语言改变
  • 片段布局有些不需要,或者需要重新创建内容
  • 其他变化
  • 我清除所有Fragments并将其全部设置为null处于活动状态,但是Fragment已经创建了它自己,而它的主机活动是bean set null,因此在调用Fragment view之前检查它是否为null

    例如

    Activity{
        fragment
        recreate{
           fragment = null then new instance
        }
    
    }
    
    Fragment{
        if((activity).fragment != null) {
           findViewById()
        }
    
    }
    By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
    Licensed under cc by-sa 3.0 with attribution required.