Android Fragment找不到ID的视图?

Posted

技术标签:

【中文标题】Android Fragment找不到ID的视图?【英文标题】:Android Fragment no view found for ID? 【发布时间】:2011-11-22 09:50:32 【问题描述】:

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

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_activity41882f50 #2 id=0x7f080011

feed_parser_activity 是在 xml 中设置为 Fragment 布局的 Fragment。 我正在使用 FragmentActivity 来托管包含 feed_parser_layout 的片段布局。 我上面的编码是否正确?

【问题讨论】:

可以包含 XML 吗? 在Activity中调用setContentView之前进行fragment事务也会出现同样的错误 只有在使用 ViewPager->Fragment->RecyclerView->Fragment with childFragmentManager 时才会在 android 5 和 Android 6 中面临同样的问题 【参考方案1】:

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

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

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

【讨论】:

setContentView 中指定布局的子级是什么意思?如何让它成为孩子? 如果在 XML 的父视图中声明,则视图是另一个视图的子视图。 IE。 RelativeLayout 内的 TextViewRelativeLayout 的子代。 @howettl:我知道这篇文章有点老了。但我无法用你的回答解决这个问题。这是一个问题:***.com/questions/25844394/… - 你能帮我解决这个问题吗?谢谢! 发生在我身上。 CTRL+C CTRL+V 的缺点。 你是一个救生员。我错误地删除了主片段中的include 代码,然后我被困了 2 个小时试图解决这个问题。【参考方案2】:

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

【讨论】:

我的情况正好相反。试图通过调用 getChildFragmentManager() 添加到主片段容器。指出这一点为我解决了这个问题。谢谢+1 @Malachiasz:你能看看这个关于 ViewPager 的问题吗?谢谢***.com/questions/27937250/… 这正是我的问题,谢谢。奇怪的是,这仅在调用 .show() 时发生在横向。用它来替换主要片段效果很好。 这正是我的问题,非常感谢!它只发生在一些速度较慢的设备上,所以很难理解到底发生了什么。 多次提出这个问题后,我觉得没有其他人有我的问题,只需要向下滚动一点。如果他们能让错误代码更具体地说明可能是这种情况,那就太好了。【参考方案3】:

解决方案是使用getChildFragmentManager()

而不是getFragmentManager()

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

这样就解决了问题。

【讨论】:

@surfer190 改用getSupportFragmentManager() 更改为 getChildFragmentManager() 并且这有效!! 在我的情况下,我在底部页面片段中使用 viewpager 使用片段导航。您的解决方案效果很好!!吨的谢谢兄弟。 遇到了同样的问题,这为我解决了! getChildFragmentManager() 而不是 getActivity().getFragmentManager() 一旦我想到它就有意义了:) TY! 我正在从一个活动中调用该方法,但现在不推荐使用getFragmentManager()【参考方案4】:

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

当你在内部fragment(ViewPager的页面)做Fragment事务时,你需要

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

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

【讨论】:

是的......对我来说,除此之外所有其他实现都很好。我直接尝试访问这样的代码: FragmentTransaction transaction =getSupportFragmentManager().beginTransaction();然后我像你提到的那样单独使用 getActivity() 获得了片段管理器。它工作得很好【参考方案5】:

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

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

【讨论】:

我在使用 viewPager 时遇到了同样的问题。在执行事务之前使用 viewPager.setCurrentItem(n) 修复了相同的错误。也许它对某人有用。 在我的情况下,方向相似,但问题是我在 .setID 中使用了负值。使用正整数解决了这个问题。【参考方案6】:

在我的例子中,我试图显示一个包含寻呼机的 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;
    

【讨论】:

getChildFragmentManager() 无法从 DialogFragment 访问 可访问。这个解决了我的问题。谢谢 这拯救了我的一天。在看到这个答案之前,我试图在对话框中使用Material Stepper 无济于事【参考方案7】:

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

【讨论】:

如果 id 不是唯一的,编译器不会报告 current 布局中是否缺少 id,因此真正的问题不是 id 的唯一性,而是当前布局中的 id。【参考方案8】:

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

您的 logcat 显示“未找到 id 0x7f080011 的视图”。

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

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

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

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

【讨论】:

不错。在带有 LinuxOS 的 Android Studio 中,它位于:/home/bob/AndroidStudioWorkspace/HelloWorld/app/build/generated/source/r/release/android/support/v7/appcompat。【参考方案9】:

带有嵌套片段

对我来说,使用 getChildFragmentManager() 而不是 getActivity().getSupportFragmentManager() 解决了崩溃

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

【讨论】:

但在适配器内部无法输入 getchildFragmentManger 为什么【参考方案10】:

当我从 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_
    android:layout_>
</FrameLayout> 

到这里:

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

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

</FrameLayout> 

所以布局必须有一个子视图。我假设他们在新图书馆中强制执行了这一点。

【讨论】:

【参考方案11】:

我知道这已经针对一种情况得到了解答,但我的问题略有不同,我想我会分享一下,以防其他人站在我的立场上。

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

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

【讨论】:

嗯...在我的情况下,这样的代码是在 onCreate 还是 onResume 中没有区别 @IgorGanapolsky 在我的情况下也是,通过片段的onAttach 的回调解决了这个问题。见我的answer 这正是我的问题。调用另一个类来刷新视图状态是在尚未膨胀的布局上执行片段事务。在 onResume() 中调用它可以解决问题。 onResume() 中,确保在 super.onResume() 之后尝试使用 FragmentManager。 【参考方案12】:

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

有趣的是,我在同一个 RecyclerView 中有两个 Viewpager,并且两个 Viewpager 都相距大约 5 个单元格(其他在屏幕上不可见,它已关闭)。所以最初我只是将解决方案应用于第一个 Viewpager 并保留另一个原样(Viewpager using Fragments)。

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

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

java.lang.IllegalArgumentException: No view found for id 0x7f0c0098 (com.kk:id/pagerDetailAndTips) for fragment ProductDetailsAndTipsFragment189bcbce #0 id=0x7f0c0098

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

没有任何效果。

最后,我没有使用 FragmentStatePagerAdapter ,而是扩展了 PagerAdapter 并在 Viewpager 中使用它而不使用 Fragment。我相信有些地方有嵌套片段的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;

希望对您有所帮助!!

【讨论】:

是的,这个解决方案有效,但是如果我需要用自己的生命周期和变量进行困难的构造,而不仅仅是视图呢?它将与带有播放和静音按钮的 videoViews 和 imageViews 一起使用。对我的情况没有任何帮助? 我相信是这个原因:***.com/a/27966053/1377819【参考方案13】:

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

在我的例子中,由于不小心复制和粘贴,我在片段中使用了 DataBindingUtil.setContentView,而不是 DataBindingUtil.inflate,这会弄乱 Activity 的状态。

【讨论】:

我们怎么会犯同样愚蠢的复制和粘贴错误?那正是我的问题。谢谢【参考方案14】:

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

【讨论】:

如果您在嵌套片段中,则将您的 setRetainInstance(true) 设为 false,这将修复错误。【参考方案15】:

我的错误是在FragamentTransaction

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

不同的是,一个是布局,另一个是对layout(id)的引用

【讨论】:

【参考方案16】:

我遇到了同样的问题,让我发布我的代码,以便大家都可以看到它,而不是像我一样做同样的事情。

@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 之前设置了片段。哎呀。

【讨论】:

谢谢!我也在做同样的事情,所以我把我的setContentView 放在我的onBuildHeaders【参考方案17】:

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

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


另外,如果您已经尝试过此页面(以及整个互联网)上建议的所有其他内容,并且已经花费了好几个小时,请考虑丢弃这些烦人的片段并回到过去标准布局。 (当我最终发现我的问题时,这实际上是我正在做的事情。)您仍然可以使用容器概念。但是,您可以使用 xml include 标记来使用您在片段中使用的相同布局来填充它,而不是用片段填充它。你可以在你的主布局中做这样的事情:

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

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

</FrameLayout>

其中former_fragment_layout 是您尝试在片段中使用的xml 布局文件的名称。请参阅Re-using Layouts with include 了解更多信息。

【讨论】:

这是一个很好的建议,但是如果需要动态切换片段就行不通了。它还降低了可重用性,因为您可以将行为(代码)封装在片段中。 我绝对同意。片段要好得多。【参考方案18】:

在我的例子中,我在回收站视图项中有一个 SupportMapFragment(我使用的是开销较低的“liteMode”,它使地图看起来像非交互式的,几乎像静态图像)。我使用了正确的 FragmentManager,一切似乎都运行良好......只有一个小列表。一旦项目列表超出屏幕高度,滚动时就会出现这个问题。

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

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

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

【讨论】:

【参考方案19】:

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

使用:

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

【讨论】:

【参考方案20】:

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

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

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

【讨论】:

这终于帮助了我。谢谢一百万【参考方案21】:

当您不将&lt;include layout="@layout/your_fragment_layout"/&gt; 放入您的app_bar_main.xml 时,也会发生此问题

【讨论】:

【参考方案22】:

使用 childFragmentManager 代替活动!!.supportFragmentManager

【讨论】:

【参考方案23】:

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

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

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

【讨论】:

【参考方案24】:

当我尝试用我在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 MyProjectListFragment41692f40 #2 id=0x7f05003f myProjectListFragment

然后我通过将替换放入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();

    
    您必须在onCreateView() 中返回一个视图,以便稍后替换它 您可以在片段提升循环中的以下函数中对该视图进行任何操作,例如onActivityCreated()

希望这会有所帮助!

【讨论】:

【参考方案25】:

在我的情况下,当我为相同的布局元素(片段占位符)使用不同的 id 而同时为不同的 Build Variants 使用不同的 id 时,会引发此异常。出于某种原因,当您第一次替换片段时它工作得很好,但是如果您再次尝试这样做,您会得到这个异常。 因此,如果您对不同的 Build Variants 有多个布局,请确保使用相同的 id。

【讨论】:

【参考方案26】:

我遇到了这个问题。就我而言,我忘记在我的 Xml 文件中添加 FrameLayout,添加框架布局后,我的问题已解决。

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

【讨论】:

【参考方案27】:

如果您尝试用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);

【讨论】:

【参考方案28】:

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

核心问题是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();
    

    //...

【讨论】:

【参考方案29】:

在我的例子中,我使用片段类文件来声明一个列表视图适配器类。 我只是为公共适配器类使用了不同的文件,错误就消失了。

【讨论】:

【参考方案30】:

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

【讨论】:

这是不正确的。在这种情况下,代码甚至无法编译。

以上是关于Android Fragment找不到ID的视图?的主要内容,如果未能解决你的问题,请参考以下文章

Android 片段,在 TabHost 中找不到 id 的视图

Kotlin 在片段中找不到按钮 ID,为啥?

Android Studio XML 布局文件存在但我找不到

Android Fragment - 从一个视图移动到另一个视图?

Android ViewPager组件

在 android studio 中找不到符号错误