尊重原创:http://blog.csdn.net/yuanzeyao/article/details/39378825

关于ActionBar,相信大家并不陌生,可是真正能够熟练使用的也不是许多,这篇文章主要为大家具体介绍ActionBar的相关知识,ActionBar是在Android3.0中引入的概念,所以在2.x系统中使用ActionBar我们须要依赖ActionBarSherklock或者androi-support-v7库,ActionBarSherklock是anroid中很有名的一个开源项目,android-support-v7是Google后来推出的一个库,有了v7库后AndroidBarSherklock这个开源项目基本能够退出历史舞台了,在使用android-support-v7的过程中,一定不能仅仅使用它的jar包,由于它的jar包不包括一些重要的资源文件,我们必须导入android-support-v7project,然后让我们的project依赖它。

ActionBar的作用
1、帮助用户知道你如今处于哪个页面
2、为用户提供统一的导航界面

关于许多其它的ActionBar导航功能请參见 http://developer.android.com/guide/topics/ui/actionbar.html 我的这篇文章基本也是參考这里的

ActionBar在界面中的展现形式 例如以下图:

从图中能够看到一个ActionBar包括 APP icon,ActionItems,Action Overflow,事实上ActionBar基本就取代了曾经版本号中的菜单的概念,在不支持ActionBar的App中,假设你创建了菜单,当你点击菜单键时,下方会出来菜单,而在支持Actionbar的菜单中这些菜单向就出如今了ActionItem和Action Overflow里面了(具体请见后面),有些细心同学在平时可能会发现同一款App,在有些手机上出现了Overflow,而有些手机却没有,事实上这个是有规律的,在有菜单物理键的手机上是没有Overflow的,在没有物理菜单的手机上才有,事实上Google一直主张Android设备去掉物理菜单键,所以相信以后大部分手机都没有菜单物理键的,所以菜单的概念也会慢慢的淡化。

以下我们開始学习ActionBar吧 ,由于3.0之后的系统和2.x系统还是有略微的差别,所以我今天打算先讲讲2.x系统中ActionBar的使用,然后解说3.0之后系统ActionBar的使用。
这里我们就使用android-support-v7吧,毕竟它是Google推出来的。

在2.x上使用ActionBar的步骤

1、导入android-support-v7库,这个库事实上在你的sdk里面就有(前提是你已经下载下来了),如我的路径:D:\android-sdk-windows\extras\android\support\v7\appcompat
2、创建项目,让我们的库依赖andorid-support-v7,并让须要使用ActionBar的Activity依赖ActionBarActivity,并进行例如以下配置:

<activity android:theme="@style/Theme.AppCompat.Light" ... >

就这么简单,你的项目就已经引入了ActionBar了,假设你想隐藏ActionBar,例如以下操作就可以

ActionBar actionBar = getSupportActionBar();
actionBar.hide();

这里要提醒一下:由于ActionBar在隐藏的时候会重现绘制Activity的界面,从而填充ActionBar的空白,所以当你频繁的隐藏和显示ActionBar时,会导致Activity的界面频繁重绘,为了避免这种情况发生,你能够再actionBarStyle中将 windowActionBarOverlay这个属性设置为true,也就是说ActionBar会在Activity的上面,隐藏和显示不会影响Activity

我上面引入的ActionBar没有引入不论什么内容,默认里面就是一个设置项,如今我们就像里面增加自己的item吧
创建res/menu/main_activity_actions.xml文件并增加例如以下内容,

<menu xmlns:android="http://schemas.android.com/apk/res/android" ><itemandroid:id="@+id/action_copy"android:icon="@drawable/copy"android:title="复制"/><itemandroid:id="@+id/action_cut"android:icon="@drawable/cut"android:title="剪切"/><itemandroid:id="@+id/action_discard"android:icon="@drawable/discard"android:title="删除"/><itemandroid:id="@+id/action_edit"android:icon="@drawable/edit"android:title="编辑"/><itemandroid:id="@+id/action_email"android:icon="@drawable/email"android:title="邮箱"/></menu>

然后重写以下的方法:

@Overridepublic boolean onCreateOptionsMenu(Menu menu){// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);//返回true才会显示overflowbuttonreturn true;}

通过以上步骤,我们就已经向ActionBar中增加了5个Item,执行一下看看效果吧,例如以下图

ActionBar是出来了,可是和我们上面说的ActionBar貌似有些差别,这些item都进入了overflow了,另外就是我明明设置了icon属性,却没有看见icon
对于这两个问题,我们一一解决吧
item默认都是进入Overflow的,假设想有些重要的Item 进入ActionItem 里面,那么须要配置一个属性showAsAction

<menu xmlns:android="http://schemas.android.com/apk/res/android"xmlns:yourapp="http://schemas.android.com/apk/res-auto" ><item android:id="@+id/action_copy"android:icon="@drawable/copy"android:title="复制"yourapp:showAsAction="always"  />...
</menu>

注意这里的showAsActoin命名空间是自己定义的,不是"android",由于这个属性在2.x系统中没有,是andorid-support-v7定义的,你执行一下,会发现复制已经到了ActionItem的位置了

第二个问题就是设置了icon为什么没有显示?事实上在Actionbar中,处于ActionItem位置的item默认是显示icon而不显示title的,我们能够通过在showAsActoin中配置"always|withText",让Tiele显示出来(可是也不一定会显示,仅仅是尽量显示),而处于Overflow的item 默认是显示title而不显示icon的,这个能够通过反射机制来改变,方案例如以下:

public void setOverflowIconVisiable(Menu menu){try{Class clazz=Class.forName("com.android.internal.view.menu.MenuBuilder");Field field=clazz.getDeclaredField("mOptionalIconsVisible");if(field!=null){field.setAccessible(true);field.set(menu , true);}} catch (ClassNotFoundException e){e.printStackTrace();} catch (NoSuchFieldException e){e.printStackTrace();} catch (IllegalArgumentException e){e.printStackTrace();} catch (IllegalAccessException e){e.printStackTrace();}}

然后再onMenuOpened方法中调用

 @Overridepublic boolean onMenuOpened(int featureId, Menu menu){if(featureId == Window.FEATURE_ACTION_BAR && menu != null){setOverflowIconVisiable(menu);}return super.onMenuOpened(featureId, menu);}

执行效果例如以下图,能够看到icon已经显示了

眼下这些ActionItem和Overflowsitems都是没有响应事件的,如今为他们增加吧,假设曾经使用过菜单的同学会认为和菜单是一样的

 @Overridepublic boolean onOptionsItemSelected(MenuItem item){switch(item.getItemId()){case R.id.action_copy:Toast.makeText(this, item.getTitle(), 1000).show();return true;case R.id.action_cut:Toast.makeText(this, item.getTitle(), 1000).show();return true;case R.id.action_delete:Toast.makeText(this, item.getTitle(), 1000).show();return true;case R.id.action_edit:Toast.makeText(this, item.getTitle(), 1000).show();return true;case R.id.action_email:Toast.makeText(this, item.getTitle(), 1000).show();return true;}return super.onOptionsItemSelected(item);}

Fragment中增加ActionItem

接下来学习一下在Fragment里面使用ActionItem吧

public class MyFragment extends Fragment
{private static final String TAG = "MyFragment";@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);//一定要调用,否则无法将菜单增加ActionItemsetHasOptionsMenu(true);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){TextView tv=new TextView(this.getActivity());tv.setText("Hello Gavin");return tv;}@Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater){inflater.inflate(R.menu.fragment_men, menu);super.onCreateOptionsMenu(menu, inflater);}@Overridepublic boolean onOptionsItemSelected(MenuItem item){switch(item.getItemId()){case R.id.action_share:Toast.makeText(this.getActivity(), item.getTitle(), 1000).show();return true;}return super.onOptionsItemSelected(item);}
}

使用上和Activity差点儿相同,有一点须要注意,对于菜单的响应事件,Activity优于Fragment响应,所以在Activity的onOptionsItemSelected方法中对于没有处理的事件须要调用super.onOptionsItemSelected(item)(也能够是false,可是推荐前者),假设返回true,那么Fragment是不会执行onOptionsItemSelectedd的。

将ActionBar置于屏幕下方
假设须要将ActionBar置于屏幕下方,那么仅仅须要例如以下配置就可以

<manifest ...><activity  ... ><meta-data android:name="android.support.UI_OPTIONS"android:value="splitActionBarWhenNarrow" /></activity>
</manifest>

ActionBar的导航功能

ActionBar最重要的功能就是其导航功能,使用其导航功能时,须要进行例如以下配置
1、显示导航button
ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);
配置完了后,执行例如以下图,你会发现Actionbar多了一个相似返回的icon

2、为导航增加事件
在onOptionsItemSelected方法中增加例如以下分支推断
case android.R.id.home:
        finish();
        return true;
这个是最简单的处理,就是finish掉自身,许多其它强大的导航功能请參见后面

看到上面的导航功能预计许多同学会认为它的功能和物理返回键的功能不是一样吗?假设依照我上面的实现,确实差点儿相同,可是ActionBar真正的意图不是这种,我们知道物理返回键时依据Activity栈回退到前一个Activity,是不能直接回退到前前一个Activity的,可是ActionBar是能够的,以下就来实现以下吧

实现这个导航功能有两种实现方式
a、为当前Activity指定父Activity
b、重写 getSupportParentActivityIntent() 和onCreateSupportNavigateUpTaskStack()

当中a比較适合须要返回的父Activity比較 固定,不会由于上下文环境而改变,实现也简单,仅仅须要进行例如以下配置

<activityandroid:name="com.action.demo.SecondActivity"><meta-dataandroid:name="android.support.PARENT_ACTIVITY"android:value="com.action.demo.MainActivity" /></activity>

并重写SecondActivity的  onOptionsItemSelected方法

@Overridepublic boolean onOptionsItemSelected(MenuItem item){switch(item.getItemId()){case android.R.id.home:Intent upIntent = NavUtils.getParentActivityIntent(this);  if (NavUtils.shouldUpRecreateTask(this, upIntent)) {  TaskStackBuilder.create(this)  .addNextIntentWithParentStack(upIntent)  .startActivities();  } else {  upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  NavUtils.navigateUpTo(this, upIntent);  }  return true;  }return super.onOptionsItemSelected(item);}

b比較适合依据上下文环境选择导航到某一个Activity,比如,能够分别从MainActivity,ThreeActivity进入到SecondActivity,那么将来源标记为1和2(通过Intent 传递),重写getSupportParentActivityIntent

 @Overridepublic Intent getSupportParentActivityIntent(){if(from==1){return new Intent().setClassName(this.getPackageName(), "com.action.demo.ThreeActivity");}else if(from==2){return new Intent().setClassName(this.getPackageName(), "com.action.demo.ThreeActivity");}return super.getSupportParentActivityIntent();}

这样便能够动态的实现导航

增加ActionView

一个ActionView就是一个Widget,用来替换ActionBar中的一些button,能够在不用切换Activity和 Fragment的情况下实现一些丰富的功能,以下使用SearchView来作为样例解说ActionView的使用
   在main.xml中增加item

 <item android:id="@+id/action_search"android:title="搜索"android:icon="@drawable/search"myapp:showAsAction="ifRoom|collapseActionView"myapp:actionViewClass="android.support.v7.widget.SearchView" />

然后在onCreateOptionsMenu中增加例如以下代码

 MenuItem searchItem=menu.findItem(R.id.action_search);final SearchView searchView=(SearchView) MenuItemCompat.getActionView(searchItem);searchView.setOnQueryTextListener(new OnQueryTextListener(){@Overridepublic boolean onQueryTextSubmit(String arg0){Toast.makeText(MainActivity.this, arg0, 1000).show();searchView.onActionViewCollapsed();return true;}@Overridepublic boolean onQueryTextChange(String arg0){return false;}});

增加Action Provider

Action Provider和Action View 有些相似,和Action View不同的是当Action Provider按下的时候能够显示子菜单。以下使用ShareActionProvider为例解说ActionProvider的使用

<item android:id="@+id/action_share1"android:title="分享"myapp:showAsAction="ifRoom"myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>

在onCreateOptionsMenu中增加例如以下代码

ShareActionProvider mShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(menu.findItem(R.id.action_share1));mShareActionProvider.setShareIntent(getDefaultIntent());

执行效果例如以下图:

ShareActionProvider是Android系统自带的一个Provider,以下我们试试自己定义的Provider,我们来模仿微信中的右側的“+”号功能
public class CustomActionProvider extends ActionProvider
{private static final String TAG = "CustomActionProvider";public CustomActionProvider(Context context){super(context);}@Overridepublic View onCreateActionView(){return null;//LayoutInflater.from(getContext()).inflate(R.layout.provider_layout, null);}//这种方法是点击“+”号会默认执行的地方,注意这种方法能够被onOptionsItemSelected方法拦截掉@Overridepublic boolean onPerformDefaultAction(){Toast.makeText(this.getContext(), "onPerformDefaultAction", 1000).show();return super.onPerformDefaultAction();}@Overridepublic void onPrepareSubMenu(SubMenu subMenu){super.onPrepareSubMenu(subMenu);subMenu.clear();subMenu.add("发起群聊").setIcon(R.drawable.alluser).setOnMenuItemClickListener(new OnMenuItemClickListener(){@Overridepublic boolean onMenuItemClick(MenuItem item){return true;}});}//一定要重写该方法,并返回true,否则不会出现子菜单@Overridepublic boolean hasSubMenu(){return true;}}

在ActionBar中增加Tab

使用ActionBar中的Tab功能,使用ActionBar中的Tab功能很easy

ActionBar bar=this.getSupportActionBar();bar.setDisplayHomeAsUpEnabled(true);bar.setDisplayShowTitleEnabled(false);bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);bar.addTab(bar.newTab().setText("电影").setTabListener(this));bar.addTab(bar.newTab().setText("电视剧").setTabListener(this));bar.addTab(bar.newTab().setText("直播").setTabListener(this));

效果例如以下图

ActionBar的Style和Theme

在学习ActionBar的style和Theme之前,我们先来了解一下Style和Theme是啥吧,Style即使一些属性的集合,相似于css文件(前端开发的同学都很熟悉),Theme事实上就是Style,仅仅只是Theme是用于Activity的Style,在Android系统中自带了许多了Theme,这些Theme中有的有ActionBar,有的没有ActionBar,对于没有Actionbar的Theme对于的Activity,当调用getSupportActoin时返回null,

尽管说ActionBar是为用户提供的统一的导航功能,可是这个并不意味着全部的ActionBar都长一个样,我们还是能够依据需求进行定制的,以下我们就来学习定制自己的ActionBar
在学习自己定义ActionBar之前给大家推荐一个网址:http://jgilfelt.github.io/android-actionbarstylegenerator/  能够帮助我们进行定制ActionBar

这里我先给出竖屏和横屏的效果图,然后给出style文件,ActionBar的style属性许多,我们仅仅须要知道一些比較经常使用的,然后知道怎么查询这个属性就可以了,我能够到http://developer.android.com/guide/topics/ui/actionbar.html  ActionBar许多其它属性的使用

效果图例如以下:
竖屏图:
横屏图:
style.xml
<style name="MyActionBarTheme" parent="@style/Theme.AppCompat"><item name="android:actionBarStyle">@style/ActionBarStyle</item><item name="android:actionMenuTextColor">@color/menu_color</item><item name="android:windowActionBarOverlay">false</item><item name="android:itemBackground">@drawable/action_item_bg_selector</item> <item name="android:actionOverflowButtonStyle">@style/ActionBarOverflowStyle</item><item name="android:actionBarTabTextStyle">@style/TabTextStyle</item><item name="android:actionBarTabStyle">@style/ActionBarTab</item><!--Support Library--><item name="actionBarStyle">@style/ActionBarStyle</item><item name="actionMenuTextColor">@color/menu_color</item><item name="windowActionBarOverlay">false</item><item name="actionOverflowButtonStyle">@style/ActionBarOverflowStyle</item><item name="actionBarTabTextStyle">@style/TabTextStyle</item><item name="actionOverflowButtonStyle">@style/ActionBarOverflowStyle</item><item name="actionBarTabStyle">@style/ActionBarTab</item></style><style name="ActionBarStyle" parent="@style/Widget.AppCompat.ActionBar"><item name="android:background">@drawable/action_back</item><item name="android:titleTextStyle">@style/TitleTextStyle</item><item name="background">@drawable/action_back</item><item name="titleTextStyle">@style/TitleTextStyle</item><item name="backgroundStacked">@drawable/action_back_stack</item><item name="backgroundSplit">@drawable/action_back_stack</item></style><style name="TitleTextStyle"parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"><item name="android:textColor">@color/actionbar_text</item></style><style name="TabTextStyle"parent="@style/Widget.AppCompat.ActionBar.TabText"><item name="android:textColor">@color/actionbar_text</item><item name="android:textSize">15sp</item><item name="android:textStyle">normal</item><item name="android:maxLines">1</item></style><style name="ActionBarOverflowStyle" parent="Widget.AppCompat.ActionButton.Overflow"><item name="android:src">@drawable/more</item></style><style name="ActionBarTab" parent="Widget.AppCompat.ActionBar.TabView"><item name="android:background">@drawable/tab_indicator</item></style>

细心的同学会发现这里每一个属性声明了两遍(个别仅仅有一个),这是由于我们使用的是support-library-v7库,带前缀“android:”的是相应Android系统的,没有这个前缀的是support-librayr的。

最后给出tab_indicator的定义,这个是tab指示器的背景图片,这个并非我手动写的,我是利用上面给出的网址生成的。

<selector xmlns:android="http://schemas.android.com/apk/res/android"><!-- Non focused states --><item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@android:color/transparent" /><item android:state_focused="false" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/tab_selected" /><!-- Focused states --><item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_focused" /><item android:state_focused="true" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/tab_selected_focused" /><!-- Pressed --><!--    Non focused states --><item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed" /><item android:state_focused="false" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed" /><!--    Focused states --><item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed" /><item android:state_focused="true" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed" />
</selector>

先写到这里吧,大家有哪里没有看明确的地方欢迎留言....

转载于:https://www.cnblogs.com/blfshiye/p/4263084.html

Android导航栏ActionBar的具体分析相关推荐

  1. Android官方导航栏ActionBar(二)—— Action View、Action Provider、Navigation Tabs的详细用法...

    在上一篇文章(Android之官方导航栏ActionBar)中,我们介绍了ActionBar各组成部分的基本应用.ActionBar除了提供Action Buttons外,还提供了多种导航方式如 Ac ...

  2. Android三大按钮,模拟Android导航栏三大金刚按键点击

    模拟Android导航栏三大金刚按键点击 这里需要使用的是AccessibilityService无障碍辅助服务,可以全局监听界面所有的变化: 1.构建无障碍服务 public class Float ...

  3. android文档导航条跳来跳去,莫名其妙的Android导航栏

    iPhone的底部导航栏很是受欢迎,以至于在Android上面也有不少应用模仿.其实在开源界已经有很多不错的类似于这种导航栏的开源库,不过今天介绍的这款有些许不同,它有一个莫名的功能--在导航栏中插入 ...

  4. android双导航功能吗,Android导航栏隐藏与浮现(二)

    在Android导航栏隐藏与浮现(一)中已经以 Nexus5 为例,Android M 为基础介绍了怎么实现底部导航栏的隐藏与浮现,本文将介绍怎么在设置(辅助功能)中加入控制该功能的开关. Paste ...

  5. android导航栏隐藏与浮现

    Android M已经发布了很久了,很多新的特性也非常的吸引人,比如Doze模式可以使导航时间更长,刷到nexus5上,体验了一下确实不错.但是导航栏(虚拟按键)一直存在,感觉不是特别的爽.今天我们就 ...

  6. Android开发笔记(二十)顶部导航栏ActionBar

    标题栏ActionBar ActionBar是在Android3.0之后引入的,所以Android2.x之前的版本不能直接使用ActionBar.现在ActionBar广泛用做APP的顶部导航栏,它在 ...

  7. Android控件十二:导航栏Actionbar

    参考:https://www.cnblogs.com/mjsn/p/6150824.html 简介: Actionbar是android3.0的重要更新之一.Actionbar位于传统标题栏的位置,也 ...

  8. Android 导航栏虚拟按键

    Android 虚拟按键 Android手机可分为有导航栏以及没导航栏两种,一般有物理按键的机器不会带有导航栏,而没有物理按键的机器则基本会带,比如华为的手机基本都是带导航栏的.当然现在全面屏手机大多 ...

  9. android 导航栏半透明,Android 沉浸式/透明式状态栏、导航栏

    前言 Android 从4.4开始引进透明状态栏和导航栏的概念,并且在5.0进行了改进,将透明变成了半透明的效果.虽然此特性最早出现在ios,但不否认效果还是很赞的. 至于4.4以下的手机,就不要考虑 ...

最新文章

  1. CSS 圣杯布局升级版---多个固定宽度一个自适应宽度
  2. 魔法一样隔空在屏幕写字,捏起手指就能实现!在线可玩
  3. mysql date_format 按不同时间单位进行分组统计
  4. 科技论文的可读性-如何写好科技论文之我见(五)
  5. JSP与Servelt的区别
  6. 开源题材征集 + MVCEF Core 完整教程小结
  7. c语言函数库——ispunct函数 判断字符是否为标点符号或特殊字符
  8. Samba服务器(一):windows访问samba服务器共享文件的简单实现(图文并茂)
  9. c语言解析字符串报文,传递字符串数组报文和解析
  10. java贪吃蛇程序v1
  11. 数据结构视频教程 -《[中山大学]算法与数据结构(C语言版)[胡青主讲]》
  12. sony媒体服务器文件不对,索尼Z280断电MXF变成RSV文件完美修复
  13. 【Debug记录】Libtorch部署YOLO时cmake报错--symbol lookup error: ./test/test: undefined symbol: _ZN2at6detail1
  14. 写给大一充实,大二不顺,大三迷茫的同学
  15. py实战绘制人口金字塔图
  16. uc游览器 android系统,手机UC浏览器2019最新版
  17. eclipse配置python开发环境_Eclipse配置python开发环境
  18. oracle 表信息查询,oracle 表信息查询
  19. 设计模式(13):结构型-装饰模式(Decorator)
  20. 知云文献翻译打不开_有了这个英文文献翻译助手,SCI论文阅读不用再复制粘贴...

热门文章

  1. MATLAB App Designer GUI开发从0到1(实战篇)
  2. 数据结构期末复习之排序
  3. ElasticSearch优化系列二:机器设置(内存)
  4. 什么是激光雷达技术?
  5. 作文 深海机器人_海底寻宝机器人
  6. 地区的json数据_数据密集型系统基础:数据模型与查询语言
  7. linux内核的外部接口函数,linux内核中GPIO的使用(二)--标准接口函数
  8. 8bit黑白图像的灰度值范围是_窗宽窗位对基于互信息的医学图像
  9. 从分布式一致性谈到CAP理论、BASE理论
  10. 最详细的U-net论文笔记