Android自定义TitleBar/ActionBar

一开始我便很困惑,TitleBar和ActionBar是什么关系?
我们知道:
ActionBar是在android3.3之后推出使用的

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"                 

这意味着TitleBar似乎消失了,取而代之的是ActionBar。不过,既然是ActionBar,那么就必然支持Action事件,同理可知TitleBar只显示图片和文字,不支持事件的,所以,从某种意义上来说,可以认为ActionBar是TitleBar的升级 。

对于android3.3自定义标题栏流程如下:

一、自定义标题栏颜色和高度

直接在Activity的属性中定义即可。

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Light">
        <item name="android:windowTitleBackgroundStyle">@style/settingsTitleBg</item>
        <item name="android:windowTitleSize">40dp</item>
    </style>

    <style name="settingsTitleBg">
        <item name="android:background">#0000ff</item>
    </style>

定义标题栏背景色需要使用到Android:windowTitleBackgroundStyle属性,给这个属性指定一个style,这里为settingsTitleBg,然后在其中指定android:background的颜色即可。
指定标题栏高度只需要修改android:windowTitleSize的值即可。

二、自定义标题栏布局

调用如下方法即可:

    public static void getCustomTitle(Activity activity, String title) {
        mActivity = activity;
        mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        mActivity.setContentView(R.layout.custom_title);
        mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
                R.layout.custom_title);

        TextView textView = (TextView) activity.findViewById(R.id.title_content_text);
        textView.setText(title);
        Button titleBackBtn = (Button) activity.findViewById(R.id.title_back_button);
        titleBackBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Log.d("Title back","key down");
                mActivity.finish();
            }
        });
    }

这个方法中使用到了R.layout.custom_title布局,这个布局便是可以随意自定义的布局文件,这里指定的布局文件如下:
custom_title.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <Button
        android:layout_marginLeft="10dp"
        android:layout_gravity="center_vertical"
        android:background="@drawable/back"
        android:id="@+id/title_back_button"
        android:layout_width="20dp"
        android:layout_height="20dp" />
    <TextView
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:id="@+id/title_content_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textSize="20sp"
        android:textColor="#FFFFFF"
        />
</LinearLayout>

完成后在setContentView之前调用getCustomTitle方法即可完成自定义标题栏的工作。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏
        CustomTitle.getCustomTitle(this, "系统信息");
        setContentView(R.layout.activity_main);

CustomTitle方法的第一个参数就是当前的Activity,第二个参数是标题栏的标题。CustomTitle是我定义的一个类,其中只有getCustomTitle一个静态方法。
至此,效果如下:
这里写图片描述
这里写图片描述

三、Holo主题下自定义标题栏
现在,如果将主题从android:Theme.Light改为android:Theme.Holo.Light,那么程序会报错,如下:

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

这个时候,只需要在style中把ActionBar关掉就好了。

    <style name="AppTheme" parent="android:Theme.Holo.Light">
        <item name="android:windowTitleBackgroundStyle">@style/settingsTitleBg</item>
        <item name="android:windowTitleSize">40dp</item>
        <item name="android:windowActionBar">false</item>
    </style>

这样可以自定义标题栏,但是界面呈现出来会有闪烁,也就是默认的ActionBar会先显示出来,然后才是你自定义的标题栏,一次,在Holo主题下,这种方法不可取。

自定义ActionBar

我们也可以传入自定义的布局文件给ActionBar,方法如下:

getActionBar().setCustomView(R.layout.custom_title);

R.layout.custom_title就是我们传入的布局文件。我们也可以通过findViewById来为各个View设置监听器。但这种方式也无法便面闪烁原来ActionBar的问题,这非常讨厌。

解决自定义ActionBar闪烁原来ActionBar的问题

从原题产生的原因分析,应该是设置主题的时候造成的,主题中如果有ActionBar,那么ActionBar的绘制在Activity的布局文件绘制之前,因此,会有闪烁的问题出现。因此,我的解决方法是干脆不用ActionBar,找一个没有ActionBar的Theme,比如@android:style/Theme.Holo.Light.NoActionBar.Fullscreen。然后,使用ToolBar代替,ToolBar在Activity的布局文件中,他可以放置在布局文件的任意位置,就像一个普通的View组件一样,因此,它的绘制和Activity内容的绘制是一起的。ToolBar使用如下:

    <Toolbar
        android:id="@+id/toolbar"
        android:title="系统设置"
        android:navigationIcon="@drawable/back"
        android:background="#0000ff"
        android:layout_width="match_parent"
        android:layout_height="40dp"></Toolbar>

由于ToolBar在Activity的布局文件中使用,因此非常有灵活性。这里设置了title-标题,还有导航icon,我们还可以给导航按钮这只事件监听器,比如让Acitivity结束运行:

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

猜你喜欢

转载自blog.csdn.net/u011913612/article/details/77234910
今日推荐