{"record":{"id":"7f1ea9e6e610687b","repo":"material-components/material-components-android","slug":"only-tabitem-instances-can-be-added-to-tablayout","errorCode":null,"errorMessage":"Only TabItem instances can be added to TabLayout","messagePattern":"Only TabItem instances can be added to TabLayout","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/tabs/TabLayout.java","lineNumber":1785,"sourceCode":"  public void addView(View child, int index) {\n    addViewInternal(child);\n  }\n\n  @Override\n  public void addView(View child, ViewGroup.LayoutParams params) {\n    addViewInternal(child);\n  }\n\n  @Override\n  public void addView(View child, int index, ViewGroup.LayoutParams params) {\n    addViewInternal(child);\n  }\n\n  private void addViewInternal(final View child) {\n    if (child instanceof TabItem) {\n      addTabFromItemView((TabItem) child);\n    } else {\n      throw new IllegalArgumentException(\"Only TabItem instances can be added to TabLayout\");\n    }\n  }\n\n  @NonNull\n  private LinearLayout.LayoutParams createLayoutParamsForTabs() {\n    final LinearLayout.LayoutParams lp =\n        new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);\n    updateTabViewLayoutParams(lp);\n    return lp;\n  }\n\n  private void updateTabViewLayoutParams(@NonNull LinearLayout.LayoutParams lp) {\n    if (mode == MODE_FIXED && tabGravity == GRAVITY_FILL) {\n      lp.width = 0;\n      lp.weight = 1;\n    } else {\n      lp.width = LinearLayout.LayoutParams.WRAP_CONTENT;\n      lp.weight = 0;","sourceCodeStart":1767,"sourceCodeEnd":1803,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/tabs/TabLayout.java#L1767-L1803","documentation":"TabLayout overrides ViewGroup.addView so that any child added to it is interpreted as tab metadata: only TabItem elements are accepted (they are converted into tabs via addTabFromItemView). Any other View passed to addView hits addViewInternal's else branch and throws IllegalArgumentException.","triggerScenarios":"In XML, placing any element other than <com.google.android.material.tabs.TabItem> inside the TabLayout (e.g. TextView, ImageView, Space). Programmatically, calling tabLayout.addView(someView).","commonSituations":"Declarative XML with a typo'd or wrong child element; trying to overlay a badge/icon view directly inside TabLayout instead of using tab.setBadge()/tab.setIcon(); using TabItem without the fully qualified name.","solutions":["In XML, only use <com.google.android.material.tabs.TabItem android:text=\"...\"/> children.","To show icons/badges/labels, use Tab APIs (setIcon, setCustomView, getOrCreateBadge) instead of adding views.","For custom content per tab, supply tab.setCustomView(layoutRes) rather than addView."],"exampleFix":"<!-- before -->\n<com.google.android.material.tabs.TabLayout>\n  <TextView android:text=\"Tab 1\"/>\n</com.google.android.material.tabs.TabLayout>\n\n<!-- after -->\n<com.google.android.material.tabs.TabLayout>\n  <com.google.android.material.tabs.TabItem android:text=\"Tab 1\"/>\n</com.google.android.material.tabs.TabLayout>","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"if (child instanceof com.google.android.material.tabs.TabItem) {\n  tabLayout.addView(child);\n} else {\n  throw new IllegalArgumentException(\"Child must be TabItem, was \" + child.getClass().getName());\n}","tryCatchPattern":null,"preventionTips":["Only declare <com.google.android.material.tabs.TabItem> children in TabLayout XML.","Use tab.setCustomView()/setIcon()/getOrCreateBadge() instead of adding views directly.","Lint for raw addView calls on TabLayout."],"tags":["tablayout","xml","tabs","android"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}