ToolBar、ActionBar与Menu的纠葛(以及navigationIcon、setHomeButtonEnabled、setDisplayHomeAsUpEnabled)
因为贴图的繁琐。。。所以下面是无图版。。。完整的在这里:
探究一下toobar和actionbar在使用menu时的吊诡情况
- toolbar最近比较火,而且是出出来代替actionbar的,但是目前还没有完全代替
- 但其实actionbar也是在Android 3.0(API 11)中才加入到SDK中的,也并不古老
- 更早的还有tittle bar(不带menu),Action Bar取代了传统的tittle bar和menu,在程序运行中一直置于顶部
- ActionBar和TitleBar是同一个位置的 都是在状态栏下
- ActionBar 是3.3版本后推出的,上面可以放入按钮,或下拉式的按钮.可以有文字,logo等信息.还可以设置返回按钮等信息
- TitleBar只有APP图标和文字.不支持点击事件
- ActionBar的图标,可显示软件图标,也可用其他图标代替。当软件不在最高级页面时,图标左侧会显示一个左箭头,用户可以通过这个箭头向上导航;
- 如果你的应用要在不同的View中显示数据,这部分允许用户来切换视图。一般的作法是用一个下拉菜单或者是Tab选项卡。如果只有一个界面,那这里可以显示应用程序的标题或者是更长一点的商标信息;
- 两个action按钮,这里放重要的按钮功能,为用户进行某项操作提供直接的访问;
- overflow按钮,放不下的按钮会被置于“更多...”菜单项中,“更多...”菜单项是以下拉形式实现的
- 当Activity启动的时候,系统会调用Activity的onCreateOptionsMenu()方法(这个方法和onCreate方法是同一级别)来取出所有的menu按钮,我们只需要在这个方法中去加载一个menu资源,并把所有的Action按钮都定义在资源文件里面就可以了
- 这个menu资源就是一个xml文件,细节不讲,大概是这样,一看就懂
- 然后重写Activity的onCreateOptionsMenu()方法,代码如下所示:
-
- 通过getMenuInflater()方法能够得到MenuInflater对象,再调用它的inflate()方法就可以给当前活动创建菜单了
- inflate()方法接收两个参数,第一个参数用于指定我们通过哪一个资源文件来创建菜单,这里当然传入R.menu.main,第二个参数用于指定我们的菜单项将添加到哪一个Menu对象当中,这里直接使用onCreateOptionsMenu()方法中传入的 menu参数
- 然后给这个方法返回true, 表示允许创建的菜单显示出来, 如果返回了false, 创建的菜单将无法显示
- 第一步完成后,这个菜单就可以显示出来了(具体怎么显示下面再说),但是仅仅让菜单显示出来是不够的,我们定义菜单不仅是为了看的,关键是要菜单真正可用才行,因此还要再定义菜单响应事件。
- 我们继续在Activity中重写 onOptionsItemSelected()方法:
-
- 当用户点击按钮的时候,系统会调用这个方法,通过方法传入的MenuItem参数,我们可以调用它的getItemId()方法和menu资源中的id进行比较,从而辨别出用户点击的是哪一个Action按钮
- 你会发现到这里我都没有介绍实现的效果,而且前面我还说menu系统是独立的
- 对的,就是这样,menu系统是跟titlebar一个时代的东西,而titlebar中是不能定义menu的,它是两个东西,我们后来见得很多的menu放在标题栏里的样子其实是后来actionbar中才能实现的
- 而后来虽然titlebar被淘汰,甚至actionbar都要被淘汰,但是menu系统却一直在,只是被整合了,所以说,单独拿出menu系统来研究还是非常有价值的
- 最初的时候只有titlebar,一定有实体(物理)的menu按键,menu系统在点击 menu 按键 后会在对应的Activity底部显示出来。这其实就是最初的menu的完全体
- 很多资料已经说不建议使用,因为用户看不到,不一定会去点实体菜单
- 之后有了actionbar,但实际中可以设置可以不设置,而实体的menu按键可能有可能没有,情况就复杂一些了
- 如果没有定义actionbar,那么你定义的菜单就是通过点击实体的menu按键,然后在对应的Activity底部显示出来,跟上面一样
- 如果你定义了actionbar,而且没有实体menu按键,那就是标准的情况,你定义的menu会全部出现在actionbar的这两个位置,根据你为了actionbar增加设置的显示属性(不设置默认不显示在actionbar上)
- 如果你定义了actionbar,同时有实体menu按键,那就是不标准的情况,你定义menu会一部分出现在actionbar上,另一部分原本在overflow中的按钮会出现在Activity 底部,通过你点击menu 按键召唤
- 另外说一下使用actionbar的功能本身不用另外设置,因为它默认是包含在主体中的
- 从Android3.0(API级别 11)开始,Action bar被包含在所有的使用Theme.Hole主题的Activity(或者是这些Activity的子类)中,当targetSdkVersion或minSdkVersion属性被设置为“11”或更大的数值是,这个主题是默认的主题一
- 默认情况下,应用程序图标显示在操作栏的左边,你能够把这个图标当做操作项来使用
- 从Android4.0(API 级别 14)开始,必须通过调用actionbar.setHomeButtonEnabled(true)方法确保这个图标能够作为一个操作项
- 在以前的版本,默认情况下,这个图标就能够作为一个操作项
- 当用户触摸这个图标时,系统会调用Activity带有android.R.id.home ID的onOptionsItemSelected()方法
- 也就是说,整个过程是:
- 通过调用actionbar.setHomeButtonEnabled(true)方法增加一个按钮(普通的Menu按钮是先定义xml,再通过一个方法引入这个xml)
- 直接在跟普通menu按钮一样的地方(onOptionsItemSelected()方法 )中定义按钮被点击后执行的方法,但它的ID固定是 android.R.id.home
- 这个功能一般设置为返回,但这个图标导航其实用得不多,因为用户不友好
- actionbar返回图标导航在形式上就是在ActionBar图标(如果没有设置图标icon,文字标题也可以代替)的左侧添加了一个向左的箭头,通常情况下这都表示返回的意思
- 这里一个高级用法,其实也是actionbar图标导航本质的东西是:与返回按钮不一样的层级关系。这点很有用,但是在这里不用讲,另外的笔记中我写了非常详细的内容。这里我们就把它当成最简单的返回来用
- 样子大概是这样
- 它的使用方法跟上面图标导航非常像
- 通过actionBar.setDisplayHomeAsUpEnabled(true);增加一个按钮
- 直接在跟普通menu按钮一样的地方(onOptionsItemSelected()方法 )中定义按钮被点击后执行的方法,但它的ID固定是 android.R.id.home(跟上面那个的ID一毛一样)
- 这个用得还算多
- actionbar.setHomeButtonEnabled(true);确保icon图标能够作为一个操作项被点击
- actionBar.setDisplayHomeAsUpEnabled(true);在ActionBar图标(如果没有设置图标icon,文字标题也可以代替)的左侧添加了一个向左的箭头
- actionBar.setDisplayShowHomeEnabled(true);使左上角图标是否显示,如果设成false,则没有程序图标,仅仅就个标题,否则,显示应用程序图标
- actionBar.setDisplayShowTitleEnabled(true) ;使左上角标题是否显示
- actionBar.setDisplayShowCustomEnabled(true);使自定义的普通View(比如输入框)能在title栏显示,即actionBar.setCustomView能起作用
- 对于toolbar与menu的关系我没找到比较详细的说明,下面都是我根据实际应用的体会总结而来的,总体感觉是非常不适,非常撕裂,体验不怎么好
- (上面的说法已经由我自己的探索推翻了,感觉非常好,我喜欢toolbar哈哈)
- toolbar是5.0之后有的,是design包中的控件,它的特点是增强了跟其他东西的支持,能自定义更多的东西,简化了很多功能的使用,谷歌希望用它来代替actionbar
- 先写一个menu的xml,这个跟经典的形式一样
- 然后在activity的xml中增加一个toolbar的view
- 然后在onCreate方法中为toobar绑定menu的xml和定义menu事件,跟经典的形式差不多,但不是一个东西
- 你只需要在onCreate方法中给你的DrawerLayout配置一个ActionBarDrawerToggle就好了,其他什么都不用做,icon会自动出现,监听事件什么都不用写
- 在说这个之前,我们来简单回忆一下actionbar关于这块的内容
- actionbar左侧可以设置两个按钮(不知道能不能同时设置)
- 他们的回调事件ID都是android.R.id.home
- 他们的icon不可更改(appicon就当成不可改),返回的icon不好看
- 点击事件跟actionbar上的menu的点击事件写在一起
- 而在toolbar中
- toolbar左侧可以自行添加一个任意图片的icon,(在xml中在代码中都可以,是一样的),名字叫navigationIcon
- 但是这个navigationIcon 无法设置点击事件(真是找遍了都找不到,跟toolbar上menu的点击事件写一起不顶用)
- 于是需要采用一种非常蛋疼的退化的写法:重新召唤actionbar,这种写法非常撕裂
- 我使用了搜索技能,搜索我设置icon用的关键词:
- 找到了几次,有几个方法
- 其中最后这个方法我认为非常可疑,于是我尝试在代码中写了这样一个监听器,然后我运行程序,尼玛!居然成功了!
- toolbar左侧可以自行添加一个任意图片的icon,(在xml中在代码中都可以,是一样的)
- 通过toolbar的方法设置这个按钮的监听事件
- toolbar左侧可以自行添加一个任意图片的icon,(在xml中在代码中都可以,是一样的)
- 但是这个icon无法设置点击事件(真是找遍了都找不到,跟toolbar上menu的点击事件写一起不顶用)
- 于是需要采用一种非常蛋疼的退化的写法:重新召唤actionbar,这种写法非常撕裂
- 召唤actionbar(不管是设置了主题是有actionbar还是noactionbar都而已)
- 把toolbar通过setSupportActionBar(toolbar)方法,把actionbar的内核换成toolbar,于是你获得了一个披着actionbar皮的toolbar
- 于是你把Toolbar当做ActionBar给设置了,menu可以像ActionBar一样用和处理
- 于是的navigationIcon 监听自动变成了对ID为android.R.id.home 的监听
- 先写一个menu的xml,这个跟经典的形式一样
- 然后在activity的xml中增加一个toolbar的view
- 在toolbar的view的xml中自行添加一个任意图片的navigationIcon(这里使用了系统默认的返回icon)
- 然后在onCreate方法中
- 增加调用setSupportActionBar(toolbar)方法进行狸猫换太子。这句话的位置好像非常关键,必须在这个地方才行。
- 减去使用toolbar绑定menu的xml
- 使用toobar定义menu事件的方法不变
- 使用menu原始的方法给toolbar绑定menu的xml
- 使用menu原始的方法给actionbar的home按钮绑定事件,ID是android.R.id.home ,其实就是在给我们toolbar的navigationIcon 绑定事件
- 结束,现在toolbar上能显示navigationIcon 和menu的按钮,而且都绑定了点击事件,整个过程非常撕裂
- 其实当时也有想,既然这样,为什么不直接用actionbar来实现呢,当时觉得只有一个原因,那就是actionbar的返回icon不好看,又不能自定义
ToolBar、ActionBar与Menu的纠葛(以及navigationIcon、setHomeButtonEnabled、setDisplayHomeAsUpEnabled)的更多相关文章
- android开发学习——关于activity 和 fragment在toolbar上设置menu菜单
在做一个项目,用的是Android Studio 系统的抽屉源码,但是随着页面的跳转,toolbar的title需要改变,toolbar上的menu菜单也需要改变,在网上找了好久,也尝试了很多,推荐给 ...
- 动态改变actionbar上menu的图标
工作中遇到了一个需求是,在滚动的时候让actionbar上的图标进行变色.实现后在这里总结下思路. 一.先在主题中定义好Actionbar的style <style name="App ...
- Java基础之处理事件——添加菜单图标(Sketcher 8 with toolbar buttons and menu icons)
控制台程序. 要为菜单项添加图标以补充工具栏图标,只需要在创建菜单项的Action对象中添加IconImage对象,作为SMALL_ICON键的值即可. // Defines application ...
- Android ActionBar以及menu的代码设置样式
menu部分xml代码 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android= ...
- 如何在有实体键的情况下全部显示ActionBar的Menu?
大伙都知道, 在老版本手机, 以及部分的新手机上都还残留实体键, 有了这些实体键, 默认菜单是用实体菜单键呼出的, 尽管你把android:showAsAction="always" ...
- android.support.v7.widget.Toolbar 中menu图标不显示问题
<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http:// ...
- android ActionBar 去掉menu分隔线
自定义Theme继承原来Theme修改其中的分隔线: <item name="actionBarDivider">@null</item> 低版本设置 & ...
- ToolBar教程:AppCompatActivity下用toolbar当actionbar用
参考: https://developer.android.com/training/appbar/index.html 1,自定义toolbar主题 2,在布局xml中使用toolbar 3,在代码 ...
- ToolBar控件详解
ToolBar控件详解 在Activity中添加ToolBar 1.添加库 dependencies { ... compile "com.android.support:appcompat ...
随机推荐
- old header
海纳百川 山不拒土 No Backspace in Real Life. Love Life![Cloud][LBS][GIS][GPS][MAPS][C++][Java]
- [sicp]huffman编码的实现 @ Scheme
#lang racket (define (length items) (if (null? items) (+ (length (cdr items))))) (define (element-of ...
- [算法导论]二叉查找树的实现 @ Python
<算法导论>第三版的BST(二叉查找树)的实现: class Tree: def __init__(self): self.root = None # Definition for a b ...
- Android开发(三十一)——重复引用包错误Conversion to Dalvik format failed
错误:Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Landroid/sup ...
- C# WinForm 技巧八:界面开发之“WeifenLuo.WinFormsUI.Docking+OutLookBar” 使用
概述 最近几天一直在关注WinFrom方面的文章主要还是园子里伍华聪的博客,在看看我们自己写的项目差不忍赌啊,有想着提炼一下项目的公共部分,公共部分有分为 界面,类库两方面,今天主要是把界面 ...
- Akismet API 密钥(key)免费获取方法
Akismet插件是用户使用最广泛的垃圾评论插件,也是wordpress的创始人制作的,同时它也毫无疑问的成为wordpress的默认安装插件,这样的插件可以帮助用户解决垃圾评论的烦恼,而且也不用访客 ...
- java.util.Properties类
http://trans.blog.51cto.com/503170/110227/ http://soft.chinabyte.com/database/395/12625895.shtml
- android 内置视频目录
在做引导界面的时候有一个视频文件, 把它放在res/raw目录下面. 引用方法 如下: videoView = (VideoView) findViewById(R.id.video_view); v ...
- SQLSERVER吞噬内存解决记录
现在手上有一个不大不小的系统,运行了一段时间,因为是24*7不断运行,所以内存逐渐增高,慢慢的会飙到95%以上,然后不得不重启电脑,因为用的是云,怕虚拟机重启down掉起不来,重启操作还只能在凌晨4. ...
- Xcode编译错误集锦
1.在将ios项目进行Archive打包时,Xcode提示以下错误: [BEROR]CodeSign error: Certificate identity ‘iPhone Distribution: ...