这是我自己封装的一个activity,主要作为所有Activity的基类,可以一键关掉所有的activity, 并共享一个自定义actionbar.直接切入主题吧。

第一步就是创建自定义标题的布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rel_bar_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/left_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="8dp"
        android:visibility="gone" />

    <TextView
        android:id="@+id/bar_left_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="4dp"
        android:layout_toRightOf="@id/left_icon"
        android:text=""
        android:textColor="@android:color/white"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/bar_second_left_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="6dp"
        android:layout_toRightOf="@id/bar_left_btn"
        android:text=""
        android:textColor="@android:color/white"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/bar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:ellipsize="end"
        android:maxWidth="150dp"
        android:singleLine="true"
        android:text=""
        android:textColor="@android:color/white"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/bar_right_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/right_icon"
        android:textColor="@android:color/white"
        android:textSize="18sp"
        android:visibility="gone" />

    <ImageView
        android:id="@+id/right_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="8dp" />

</RelativeLayout>

从左至右,依次分为左图标,左标题,标题,右标题,右图标。。。可以根据需要来显示或隐藏

再来代码实现自定义标题

            ActionBar actionBar = this.getSupportActionBar();
            actionBar.setDisplayOptions(16);
            actionBar.setDisplayShowCustomEnabled(true);
            actionBar.setCustomView(layout.action_bar_layout1);     //这个当然是上面定义的布局文件咯
            this.mRelBarContainer = (RelativeLayout)actionBar.getCustomView().findViewById(id.rel_bar_container);
            this.mTvLeft = (TextView)actionBar.getCustomView().findViewById(id.bar_left_btn);
            this.mTitle = (TextView)actionBar.getCustomView().findViewById(id.bar_title);
            this.mIvLeftIcon = (ImageView)actionBar.getCustomView().findViewById(id.left_icon);
            this.mIvRightIcon = (ImageView)actionBar.getCustomView().findViewById(id.right_icon);
            this.mTvRight = (TextView)actionBar.getCustomView().findViewById(id.bar_right_btn);
            this.mTvSecLeft = (TextView)actionBar.getCustomView().findViewById(id.bar_second_left_btn);
            this.initBarButtonListener(); //为每个按钮定义监听事件接收方法

activity继承support.v7的activity, 用到的actionbar也就是android.support.v7.app.ActionBar。接着再来看监听事件方法实现

import android.support.v7.app.AppCompatActivity;
/**
 * Created by 28205 on 2016/6/3.
 */
public class CustomActionBarActivity extends AppCompatActivity {
        ...
        private void initBarButtonListener() {
        View.OnClickListener leftListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onLeftClick();
            }
        };

        View.OnClickListener leftSecListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onLeftSecondClick();
            }
        };

        View.OnClickListener leftIconListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onLeftIconClick();
            }
        };

        View.OnClickListener rightListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onRightClick();
            }
        };

        View.OnClickListener rightIconListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onRightIconClick();
            }
        };
        //set listener
        mTvLeft.setOnClickListener(leftListener);
        mIvLeftIcon.setOnClickListener(leftIconListener);
        mTvSecLeft.setOnClickListener(leftSecListener);
        mTvRight.setOnClickListener(rightListener);
        mIvRightIcon.setOnClickListener(rightIconListener);
    }
    public void setBarBg(int resid) {        mRelBarContainer.setBackgroundResource(resid);    }
}

很明显,该类还得要定义几个空的事件监听方法来让子类继承,以达到子类来重写自己的监听方法。不过这里并没有将其设为接口或虚方法来强制用户来重写这几个方法,而是记子类根据需要自己来决定重写,如不重写,当然就是点击不响应咯。

public void onLeftClick() {
    }

    public void onLeftSecondClick() {
    }

    public void onLeftIconClick() {
    }

    public void onRightClick() {
    }

    public void onRightIconClick() {
    }

好了,标题这块基本上完了,再来看一键关所有activity,这个在面试的时候经常会被问到,我之前就在这上面吃了大亏,伤心。。。在这我是通过广播的方式来做到,只要收到自定义的“关闭所有”的广播就将自己关掉,而所有的activity都是继承这个基类,所以

也就是能做到所有的activity能同时关闭了。代码简单,一目了然

public class CustomActionBarActivity extends AppCompatActivity {

    public static final String ACTION = "FINISH_ALL";
    private FinishReceiver mFinishReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       ...

        mFinishReceiver = new FinishReceiver();
        startMonitoring();
    }

    protected void startMonitoring() {
        IntentFilter intentFilter = new IntentFilter(ACTION);
        registerReceiver(mFinishReceiver, intentFilter);   //简单的广播注册
    }

    protected void stopMonitoring() {
        unregisterReceiver(mFinishReceiver);
    }

    /**
     * 关闭所有的Activity
     */
    public void finishAll() {                  // 只要在子类调用该方法,就能关闭所有activity了,除非你不是该类的子类
        sendBroadcast(new Intent(ACTION));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopMonitoring();
    }

    /**
     * 退出监听
     */
    class FinishReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // 监听退出消息
            if (intent.getAction() == ACTION) {
                finish();
            }
        }
    }

上面的代码可以做成jar包供自己使用,以后就不需要每次都要重写了,最后看看怎么使用。这里只说说自定义的标题的使用和配置,首先得为标题设置一个自己的theme, 不然就会用系统默认的

<resources xmlns:tools="http://schemas.android.com/tools">

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

    <style name="Theme.Custom.AppCompat" parent="@style/Theme.AppCompat.Light">
        <item name="android:actionBarSize">50dp</item>       //actionbar高度
        <item name="android:windowContentOverlay">@null</item>
        <item name="actionBarStyle">@style/bc</item>
    </style>

    <style name="bc" parent="@style/Widget.AppCompat.ActionBar">
        <item name="background">@android:color/holo_blue_dark</item>
        <item name="contentInsetStart">10dp</item>   //以下4个选项必须为0, 否则会在两边留白,这里我故意设为10dp,对比下效果
        <item name="contentInsetEnd">0dp</item>
        <item name="android:paddingLeft">0dp</item>
        <item name="android:paddingRight">0dp</item>
        <item name="elevation">0dp</item>
    </style>

</resources>

例子

public class BaseActionBarActivity extends CustomActionBarActivity {
    private static final String TAG = "BaseActionBarActivity";
    Dialog dialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTheme(R.style.Theme_Custom_AppCompat);
        setBarBg(R.color.red);   // 这个方法就是指定标题的背景色,如果没有指定,背景色就使用上一句的theme里定义的颜色,如果有则会覆盖。
//        setStatusBarColor(R.color.app_theme_color);
        setLeftTitle("左标题");
    }

    @Override
    public void onLeftClick() {
        super.onLeftClick();
        Log.d(TAG, "onLeftClick 左标题被点了");
    }
}

效果是这样的

很显然,actionbar左边有10dp的没有覆盖住,这就是在theme里定义的<item name="contentInsetStart">10dp</item> 的效果。

最后再美化一下界面,加入沉浸式状态栏,让状态栏背景与actionbar颜色一致。这个功能是谷歌在android4.4版本后推出的。这里使用三方库SystemBarTint

链接:https://github.com/jgilfelt/SystemBarTint

android studio导入方法

// 沉侵模式菜单
    compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'

代码块实现

package com.blueto.cn.myutils.activity;

import com.readystatesoftware.systembartint.SystemBarTintManager;

/**
 * Created by 28205 on 2016/6/3.
 */
public class CustomActionBarActivity extends AppCompatActivity {
    private SystemBarTintManager tintManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            ...
            initSystemBar(this);
    }

    private void initSystemBar(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (!showSystemBar) return;
            setTranslucentStatus(activity, true);

            tintManager = new SystemBarTintManager(activity);

            tintManager.setStatusBarTintEnabled(true);
        }
    }

    public void setStatusBarColor(int color) {
        tintManager.setStatusBarTintResource(color);
    }

    @TargetApi(19)
    private void setTranslucentStatus(Activity activity, boolean on) {
        Window win = activity.getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
        if (on) {
            winParams.flags |= bits;
        } else {
            winParams.flags &= ~bits;
        }
        win.setAttributes(winParams);
    }
}

之后在子类中就可以随意指定状态栏的颜色了

public class BaseActionBarActivity extends CustomActionBarActivity {
    private static final String TAG = "BaseActionBarActivity";
    Dialog dialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTheme(R.style.Theme_Custom_AppCompat);
        setBarBg(R.color.red);
        setStatusBarColor(R.color.red);
        setLeftTitle("左标题");

    }
}

值得注意的是,在使用沉浸式状态栏的时候,对actionbarsize这个属性有硬性要求,如果没有配置就会报错 : android.content.Resources$NotFoundException ..., 我是在这被坑了好久,最后才找到原因,因为原码里有这么一段

@TargetApi(14)
        private int getActionBarHeight(Context context) {
            int result = 0;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                TypedValue tv = new TypedValue();
                context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);
                result = context.getResources().getDimensionPixelSize(tv.resourceId);
            }
            return result;
        }

在初始化statusbar的时候,首先需要去获取actionBarSize的值,如果找不到那肯定就报错资源未找到,不过资源未找到让我把所有资源文件都确认了一次。。。

    <style name="Theme.Custom.AppCompat" parent="@style/Theme.AppCompat.Light">
        <item name="actionBarSize">50dp</item>      //报错前,这里写成了 android:actionBarSize, 郁闷啊,这错找了我一晚上
        <item name="android:windowContentOverlay">@null</item>
        <item name="actionBarStyle">@style/bc</item>
    </style>

最终效果是这样的,测试机是ZTE5.1.1版本,图中与actionbar颜色有点差异,但是在其他机型上则是完全一样的。可能还需要对这个机型做些特殊处理才能达到完全一样的效果,不过目前这个效果还是挺美的,我感觉比全一个色要好看,这样更有层次感,除非产品非要搞成一样。。

自定义actionbar标题的更多相关文章

  1. 自定义ActionBar标题与菜单中的文字样式

    自定义标题文字样式 标题样式是ActionBar样式的一部分,所以要先定义ActionBar的样式 <style name="AppTheme" parent="A ...

  2. 自定义 ActionBar 标题与菜单中的文字样式

    自定义标题文字样式 标题样式是 ActionBar 样式的一部分,所以要先定义 ActionBar 的样式 <style name="AppTheme" parent=&qu ...

  3. Android Navigation Drawer,自定义ActionBar(标题居中)

    整个示例都是改造自 Google Android Training 中的 NavigationDrawer 示例(http://developer.android.com/training/imple ...

  4. Android 自定义ActionBar

    Android 3.0及以上已经有了ActionBar的API,可以通过引入support package在3.0以下的平台引用这些API,但这儿呢,完全自定义一个ActionBar,不用引入额外ja ...

  5. Android自定义ActionBar

    Android 3.0及以上已经有了ActionBar的API,可以通过引入support package在3.0以下的平台引用这些API,但这儿呢,完全自定义一个ActionBar,不用引入额外ja ...

  6. Android——自定义Actionbar左侧覆盖不全的解决方案

    今天遇到一个很蛋疼的问题,就是在自定义Actionbar的时候,setCustomView中,自定义的view怎么也覆盖不了整个视图,左侧一直留有一个空白,看下图: 所写的部分代码如下: protec ...

  7. [安卓] 18、一个简单的例子做自定义动画按钮和自定义Actionbar

    在做安卓UI的时候有时候需自定义具有动画效果的按钮或需要自定义一下actionbar~ 本节用一个简单的demo讲如何自定义具有动画效果的按钮,以及个性化的actionbar 下面是效果: 其中: △ ...

  8. ActionBar官方教程(11)自定义ActionBar的样式(含重要的样式属性表及练习示例)

    Styling the Action Bar If you want to implement a visual design that represents your app's brand, th ...

  9. Android中自定义ActionBar的背景色等样式style

    Android中想要去自定义ActionBar的背景色等样式. [折腾过程] 1.自己找代码,发现对应的配置的地方了: AndroidManifest.xml ? 1 2 <applicatio ...

随机推荐

  1. 现代程序设计 网页前端开发作业(to 邹欣老师)

    在一些著名的网站的搜索框上,会有一种“自动完成”功能. 比如google.百度和淘宝: 现在,我们来考虑如何实现这个功能. 第一步:模仿任意一个网站,编写一个类似的网页效果原型. 在这一步,不要估计开 ...

  2. CSS 中 Font-Family 中英文对照表

    在 CSS 中,我们经常会使用 Font-Family 属性来定义字体.其中,中文字体如果直接使用中文名称,很有可能在非中文的系统环境下造成字体异常.所以通常使用字体的英文名称定义 Font-Fami ...

  3. 使用ViwePager显示图片时如何防止内存泄露。

    内存泄露的检测. 1. 在Android Studio中运行你的应用,然后切换到输出窗口的Android tab. 2. 尽情的玩耍你的应用,最好各个功能都用到,如果是Viewpager,则多滑动一些 ...

  4. MYSQL 连接数据库命令收藏

    一.MySQL 连接本地数据库,用户名为“root”,密码“123”(注意:“-p”和“123” 之间不能有空格) C:\>mysql -h localhost -u root -p123 二. ...

  5. &lt;Interview problem&gt;二进制加法

    闲来无事,搜集一些有趣的面试题,以及解决方案,有些代码可能会自己写, 有些网上有比较完整的方案了,就直接把代码拷贝过来,描述一下解题思路. Given two binary strings, retu ...

  6. RelayCommand命令

    原文:http://www.cnblogs.com/xiepeixing/archive/2013/08/13/3255152.html 常用Wpf开发中我们在ViewModel中实现INotifyP ...

  7. 微信JS-SDK

    <div class="lbox_close wxapi_form"> <h3 id="menu-basic">基础接口</h3& ...

  8. Miscellaneous--Tech

    1. Questions: 1)EF.2)MVC/MVP/MVVM.3)page lifecyle. preInit,Init,InitCompleted,preLoad,Load,LoadCompl ...

  9. python 字符串格式化 (%操作符)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在许多编程语言中都包含有格式化字符串的功能,比如C和Fortran语言中的格式化输 ...

  10. hadoop疑难杂症解析

    1:Shuffle Error: Exceeded MAX_FAILED_UNIQUE_FETCHES; bailing-outAnswer:程序里面需要打开多个文件,进行分析,系统一般默认数量是10 ...