You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio报You must call removeView() on the child's parent first错排查

报错原因

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 由DrawerBaseActivity中重写的setContentView逻辑错误触发:

  • 代码先执行container.addView(view),已经把传入的业务页面根视图(即Dashboard页面的ViewBinding根布局)添加到id为activityContainer的FrameLayout中,此时该View已经持有父容器引用
  • 后续调用super.setContentView(view)时,AppCompatActivity的父类逻辑会尝试再次把这个View添加到系统默认的内容根容器下,Android中单个View不能同时挂载到两个父容器上,因此直接抛出异常。
修复方法

修改DrawerBaseActivity的setContentView方法,将传给父类setContentView的参数从业务页面View替换为你加载出来的完整抽屉布局,修正后的代码如下:

@Override
public void setContentView(View view) {
    drawerLayout = (DrawerLayout) getLayoutInflater().inflate(R.layout.activity_drawer_base, null);
    FrameLayout container = drawerLayout.findViewById(R.id.activityContainer);
    container.addView(view);

    // 修正点:将整个抽屉布局作为Activity的根布局传给父类
    super.setContentView(drawerLayout);

    Toolbar toolbar = drawerLayout.findViewById(R.id.toolBar);
    setSupportActionBar(toolbar);
    NavigationView navigationView = drawerLayout.findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this,
            drawerLayout,
            R.string.menu_drawer_open,
            R.string.menu_drawer_close
    );
    drawerLayout.addDrawerListener(toggle);
    toggle.syncState();
}
实现逻辑说明

这种基类封装抽屉的核心思路是:

  • 把带工具栏、侧边抽屉的布局作为所有子页面的通用根布局,传给系统的setContentView完成挂载
  • 每个子页面传入的自己的布局,只需要添加到通用根布局里预留的内容容器(即activityContainer)中即可
  • 后续所有继承DrawerBaseActivity的页面,正常调用setContentView传入自身布局/ViewBinding根视图,就会自动套上通用抽屉和工具栏,不需要重复编写抽屉初始化逻辑。

内容的提问来源于stack exchange,提问作者Luqman Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 10:03:15