这是我自己封装的一个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. Struts2 的 值栈和ActionContext

    1.ValueStack 和 ActionContext 的关系与区别: -- 相同点:它们都是在一次HTTP请求的范围内使用的,它们的生命周期都是一次请求 -- 不同点:ValueStack 分为对 ...

  2. web测试安全性常见问题

    web测试安全性常见问题                  一.             登录账号明文传输 1.  问题一:登录账号密码或者修改密码明文传输 现象:目前物流对内的java系统基本上都是 ...

  3. python学习之路——基础篇(3)模块(续)

    re正则表达式.shutil.ConfigParser.xml 一.re 正则元字符和语法: 语法 说明 表达式 完全匹配字符 字符 一般字符 匹配自身 abc abc . 匹配除换行符"\ ...

  4. js/jstl/el的区别

    JavaScript 学习的路径:http://www.w3school.com.cn/js/js_intro.asp 是世界上最流行的编程语言. 这门语言可用于 HTML 和 web,更可广泛用于服 ...

  5. AndroidStudio安装教程(Windows环境下)

    AndroidStudio官网下载:http://android-studio.org/    可以更具自己喜欢的版本下载,个人推荐2.2版本以上,因为开发和运行效率快,高很多. Android St ...

  6. SWT组件添加事件的四种方式

    在我们CS日常开发过程中会经常去为组件添加事件,我们常用的为AWT与SWT.SWT的事件模型是和标准的AWT基本一样的.下面将按照事件的四种写法来实现它. 一.匿名内部类的写法 new MouseAd ...

  7. 自定义TextField清除按钮

    当需要设置TextField的清除按钮的时候,系统的总是不满足需求,这就需要我们自定义了,代码如下: // // TextFieldDemoViewController.m // OCDemo // ...

  8. 放假回来啦!!小技能:一个div不给width,怎么让它居中捏?`(*∩_∩*)′

    答案是:这个div没有浮动的话,就用text-align: center; 有的话...我也不知道了

  9. 2016 CCPC 合肥赛区 平行四边形//打铁记录..... 背锅还是我在行 此处@ctr 233

    也希望自己记住这些题并不是真的很难很难... 平行四边形... 这个题要两个直线上的两个点和给出点中的两个点组成的平行四边形面积最大. 确定两个点后,发现线上的点随之确定.那么我们解出线上的点 然后求 ...

  10. kaggle 竞赛之套路

    图片数据:卷积还是王道,有几个比较通用性的框架被人拿来改来改去 非图片特征数据:用分类: boost系列算法:牛逼的框架实现 xgboost AdaBoost算法针对不同的训练集训练同一个基本分类器( ...