Android继承AppCompatActivity与自定义窗口标题功能冲突如何解决?
步骤1:修改自定义主题继承 AppCompat 主题
将你的自定义主题父类从原生android:Theme改为Theme.AppCompat.NoActionBar,同时关闭系统自带标题特性,适配AppCompat要求:
<resources> <style name="Theme.myTheme.TitleBar" parent="@style/Theme.AppCompat.NoActionBar"> <item name="android:windowNoTitle">true</item> <!-- 保留你原有自定义配置 --> <item name="android:windowTitleSize">50dip</item> <!-- 可以按需添加其他自定义样式配置 --> </style> </resources>
Manifest中仍然使用你原来的自定义主题配置即可,不需要改成直接引用AppCompat的主题:
android:theme="@style/Theme.myTheme.TitleBar"
步骤2:移除旧版自定义标题相关代码
删掉BaseActivity中以下代码:
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
- AppCompat的NoActionBar主题已经默认禁用了系统标题栏,旧版
FEATURE_CUSTOM_TITLE是原生Framework的特性,和AppCompat的标题机制冲突,就是触发You cannot combine custom titles with other title features异常的原因。
步骤3:替换自定义标题/ActionBar实现逻辑
不需要再用劫持DecorView子View的HACK逻辑实现自定义标题,改用更稳定的全局布局注入方式:
- 先创建一个通用基础布局
activity_base.xml,包含你自定义的标题栏、内容容器、抽屉布局结构:
<!-- activity_base.xml --> <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 内容区域 --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 你的自定义标题栏布局 --> <include layout="@layout/your_custom_title_bar" /> <!-- 页面内容容器,子类Activity的布局会填充到这里 --> <FrameLayout android:id="@+id/content_container" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> <!-- 抽屉菜单布局 --> <include layout="@layout/your_drawer_menu" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start"/> </androidx.drawerlayout.widget.DrawerLayout>
- 在BaseActivity中重写
setContentView方法,统一注入基础布局:
@Override public void setContentView(int layoutResID) { // 先加载基础布局 super.setContentView(R.layout.activity_base); // 把子类Activity的布局填充到内容容器 FrameLayout contentContainer = findViewById(R.id.content_container); getLayoutInflater().inflate(layoutResID, contentContainer, true); // 在这里统一处理自定义标题栏的逻辑、抽屉菜单的逻辑即可,不需要再操作DecorView }
- 删掉原来劫持DecorView的相关HACK代码,这套实现可以完全替代原有逻辑,同时兼容AppCompat规范。
完成以上修改后,你的Activity继承AppCompatActivity不会再触发主题相关异常,ViewModelProvider(this).get(LoginViewModel.class)可以正常运行,同时自定义标题栏、抽屉菜单的功能也可以正常使用。
内容的提问来源于stack exchange,提问作者Diego Perez
相关产品推荐
相关产品推荐

