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
相关产品推荐
相关产品推荐

