Android自定义标题栏异常You cannot combine custom titles with other title features

我们在使用自定义标题栏时,一般的写法基本上是下面几步

requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_test_custom_title);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.common_titlebar);

有时候会出现如下异常

android.util.AndroidRuntimeException: You cannot combine custom titles with other title features

具体错误原因

Caused by: android.util.AndroidRuntimeException: You cannot combine custom titles with other title features
                                                                        at com.android.internal.policy.PhoneWindow.requestFeature(PhoneWindow.java:325)
                                                                        at com.android.internal.policy.PhoneWindow.generateLayout(PhoneWindow.java:3674)
                                                                        at com.android.internal.policy.PhoneWindow.installDecor(PhoneWindow.java:3981)
                                                                        at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:383)
                                                                        at android.app.Activity.setContentView(Activity.java:2166)

网上常有一些解答,都是比较模糊的,比如替换Theme等等,至于为什么如此做,没有详细说明。

于是我准备从PhoneWindow这个类的源码(android4.4,完整路径\frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindow.java)一探究竟。

首先我们从错误描述找到requestFeature方法,源码如下

public boolean requestFeature(int featureId) {
        if (mContentParent != null) {
            throw new AndroidRuntimeException("requestFeature() must be called before adding content");
        }
        final int features = getFeatures();
        if ((features != DEFAULT_FEATURES) && (featureId == FEATURE_CUSTOM_TITLE)) {

            /* Another feature is enabled and the user is trying to enable the custom title feature */
            throw new AndroidRuntimeException("You cannot combine custom titles with other title features");
        }
        if (((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) &&
                (featureId != FEATURE_CUSTOM_TITLE) && (featureId != FEATURE_ACTION_MODE_OVERLAY)) {


            /* Custom title feature is enabled and the user is trying to enable another feature */
            throw new AndroidRuntimeException("You cannot combine custom titles with other title features");
        }
        if ((features & (1 << FEATURE_NO_TITLE)) != 0 && featureId == FEATURE_ACTION_BAR) {
            return false; // Ignore. No title dominates.
        }
        if ((features & (1 << FEATURE_ACTION_BAR)) != 0 && featureId == FEATURE_NO_TITLE) {
            // Remove the action bar feature if we have no title. No title dominates.
            removeFeature(FEATURE_ACTION_BAR);
        }
        return super.requestFeature(featureId);
    }

从方法实现我们看到有两个地方会抛出这个异常。第一个if:FEATURE_CUSTOM_TITLE必须是第一个设置的,否则抛出异常。第二个if:当已经设置了FEATURE_CUSTOM_TITLE,只能再次设置FEATURE_CUSTOM_TITLE或者FEATURE_ACTION_MODE_OVERLAY,否则抛出异常。(当然设置FEATURE_CUSTOM_TITLE必须要在setContentView之前)

好了,了解了抛出异常的条件,我们定位到前一个调用的方法generateLayout,关键部分如下

if (a.getBoolean(com.android.internal.R.styleable.Window_windowNoTitle, false)) {
            requestFeature(FEATURE_NO_TITLE);
        } else if (a.getBoolean(com.android.internal.R.styleable.Window_windowActionBar, false)) {
            // Don't allow an action bar if there is no title.
            requestFeature(FEATURE_ACTION_BAR);
        }

        if (a.getBoolean(com.android.internal.R.styleable.Window_windowActionBarOverlay, false)) {
            requestFeature(FEATURE_ACTION_BAR_OVERLAY);
        }

        if (a.getBoolean(com.android.internal.R.styleable.Window_windowActionModeOverlay, false)) {
            requestFeature(FEATURE_ACTION_MODE_OVERLAY);
        }

这里有4个设置feature的地方,我们知道如果设置了FEATURE_CUSTOM_TITLE,只允许设置FEATURE_CUSTOM_TITLE或FEATURE_ACTION_MODE_OVERLAY

因此,我们只需要自定义一个主题,然后将上面前三项都设为false即可,如下

<style name="CustomTitleTheme" parent="AppTheme">
    <item name="android:windowNoTitle">false</item>
    <item name="android:windowActionBar">false</item>
    <item name="android:windowActionBarOverlay">false</item>
</style>

如此,问题解决。

End




  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值