Titlebar制作一个全局自定义标题栏

2016-09-05 / 10 阅读 / Android

利用Titlebar制作一个全局自定义标题栏

  1. 在styles.xml中定义主题

        <style name="AppTheme">
            <!-- 去掉ActionBar才能自定义 否则报错You cannot combine custom titles with other title features -->
            <item name="android:windowActionBar">false</item>
            <!-- 虽然不会导致崩溃,但是外观上会难看,不如直接去掉全部自定义 -->
            <item name="android:windowTitleBackgroundStyle">@null</item>
            <!-- 标题高度 -->
            <item name="android:windowTitleSize">50dp</item>
            <!-- 是默认的,但如果是继承某个主题的话,还是覆盖一下的好,省的出错 -->
            <item name="android:windowNoTitle">false</item>
        </style>

  2. AndroidManifest.xml中应用

        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme"> //应用主题

  3. BaseActivity中共享自定义titleBar。顺序不能乱。

    public class BaseActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
            setContentView(R.layout.activity_mail);
            getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar);
        }
    }

有时启动时会有系统默认Titlebar闪现一下,对于这个问题产生。

在系统运行一个application时,为了尽快响应用户,android首先会给用户 呈现一个app的“preview”窗口,这个界面甚至早于应用的实际进程。这个预览“preview”窗口中的信息就是从app的manifest文件 中获得的,所以一般app运行时总会显示一个具有app_name的titlebar,而不论我们在程序中如何定义我们的titlebar。

目前只找到以下解决办法:

方法一:

AndroidManifest.xml中应用一个无Titlebar的主题。待预览窗口启动后,Activity启动时,我们在把他替换回我们原来的主题。

  1. 增加主题继承我们原来主题,复写android:windowNoTitle为true

        <style name="AppTheme.NoTitle" parent="AppTheme">
            <item name="android:windowNoTitle">true</item>
        </style>

  2. AndroidManifest.xml中应用AppTheme.NoTitle

        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme.NoTitle"> //应用NoTitleBar主题

  3. 来一招偷天换日

    public class BaseActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    		setTheme(R.style.AppTheme); //关键一步,换掉主题,顺序必须在onCreate之前
    		
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
            setContentView(R.layout.activity_mail);
            getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar);
        }
    }

方法二:

既然刚开始会预先呈现一个预览窗口,那我刚开始给他一个0高度,到程序中在给它原来的高度,不就行了

    //主题中开启Titlebar,但是高度给零
    <item name="android:windowTitleSize">0dp</item>

debug看了一下DecorView的结构基本是这样的

DecorView --> LinearLayout --> ViewStub (没看)
                                               --> FrameLayout (Titlebar)
                                               --> FrameLayout (content)

 

        //获取根视图
        ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
        //获取主题布局
        ViewGroup layout = (ViewGroup) decorView.getChildAt(0);
        //获取Title所在View
        ViewGroup title = (ViewGroup) layout.getChildAt(1);
        //给定高度
        ViewGroup.LayoutParams layoutParams = title.getLayoutParams();
        layoutParams.height = 100;
相关推荐