android官方文档学习之路---ActionBar

来源:互联网 发布:淘宝cfcdk是真的吗 编辑:程序博客网 时间:2024/05/16 10:15

自学android有一定的时间了,由于自学的原因发现自己的知识很散,不够系统,因此想通过学习android官方文档和写博客的形式进行整理和总结,同时从中学到更多的知识。
由于本人是初学者的原因,难免会出现一些错误,希望大家谅解和指出。

概述

本篇主要写的是对actionBar的解析参考:1.android官方文档,文档所在目录为sdk/docs/index.html2(http://blog.csdn.net/guolin_blog/article/details/18234477#reply)

ActionBar用于确定用户的位置并提供用户操作和导航模式

官方文档中actionBar界面

1.App icon 应用的图标,通过设置可以添加一个返回图标
2.Action Button 相当于普通的Button,可以监听点击事件
3.Action overflow ,可以显示隐藏的action button

actionBar的三个部分体现了actionBar的关键功能
确定当前位置,突出重要的功能(如上图的搜索),导航和视图切换

添加ActionBar

1.创建一个Activity并继承AppCompatAcitvity(取代ActionBarActivity)
2.在AndroidManifest中,将对Activity的theme进行设置

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

一般情况下创建activity是继承Activity的,可以对theme进行如下设置

android:theme="@android:style/Theme.Holo.Light"

这时候运行项目,就可以看到actionBar了。
既然有添加actionBar当然就会有移除actionBar,移除的方式有两种
1.将theme设置为带有NoActionBar的样式即可
2.添加如下代码

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

移除actionBar,实际上就是将其隐藏,因此可以通过show()的方式将actionBar再次显示出来。

添加ActionButton

所有的actionButton和action overflow里的item 都是在menu资源文件夹下的xml文件中定义的。
所以,我们需要创建一个xml文件
这里写图片描述
在新创建的文件中添加item

<menu xmlns:tools="http://schemas.android.com/tools"      xmlns:android="http://schemas.android.com/apk/res/android">    <item android:id="@+id/action_search"          android:icon="@drawable/ic_action_search"          android:title="@string/action_search"          android:actionViewClass="android.widget.SearchView"          android:showAsAction="ifRoom|collapseActionView"          tools:ignore="AppCompatResource"/>    <item android:id="@+id/action_setting"          android:title="@string/action_settings"          android:icon="@mipmap/ic_launcher"          android:showAsAction="never"          tools:ignore="AppCompatResource"/></menu>

所添加的item是显示在action overflow里面还是显示在actionBar上,可以通过showAsAction来进行设置。
Always:总是显示在actionBar上
IfRoom:如果actionBar上的还有空间,则显示在actionBar
Never:只显示在action overflow内
withText:如果你的menu item支持同时显示title和icon时,设置withText,就会同时 显示title和icon,比如如果设置ifRoom时默认只显示icon,加上withText时就会同时 显示title和icon。

android:showAsAction="withText|ifRoom"

特别注意的是:如果item显示在action overflow内时,即使你设置了title和icon,也 只会显示title不会显示icon,因为不特别设置的话,action overflow不会显示图片。
CollapseActionView:会在下面举例介绍

创建完毕后,我们就需要在actionBar上添加我们的action,这时候我们需要重载onCreateOptionsMenu()方法。

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {   MenuInflater inflater=getMenuInflater();   inflater.inflate(R.menu.action_bar_menu,menu);   return super.onCreateOptionsMenu(menu);}

这样actionBar上就会出现我们在menu中定义的item,每个item可以被点击,但还缺少点击事件。
实现onOptionsItemSelected()方法给每个Item添加点击事件,与button实现点击方法类似。

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {   switch (item.getItemId())   {      case R.id.action_search:         //....         return true;      case R.id.action_setting:         //....         return true;      default:         return super.onOptionsItemSelected(item);   }}

一般来说上面的操作加下面的一些方法,基本上可以实现常见的actionBar了。

①去除icon
如果activity继承自Activity,添加以下代码通过选择true和false显示和隐藏icon。

getActionBar().setDisplayShowHomeEnabled(false);

如果activity继承AppCompatActivity,原本就不会显示icon,要显示Icon必须添加以下代码。

ActionBar actionBar=getSupportActionBar();actionBar.setLogo(R.mipmap.ic_launcher);actionBar.setDisplayUseLogoEnabled(true);actionBar.setDisplayShowHomeEnabled(true);

②显示导航按钮

ActionBar actionBar=getActionBar();actionBar.setDisplayHomeAsUpEnabled(true);

这里写图片描述
通过上述代码我们会发现在actionBar上多了一个箭头,这时这部分就相当于一个按钮,可以被点击同时响应点击事件。
通常增加该按钮的目的是为了实现导航的功能,即实现页面的跳转。
当我们明确需要跳转的页面时可以通过以下代码来快速实现。

<activity android:name=".SecondActivity"    android:parentActivityName=".MainActivity">//想要返回的activity    <meta-data       android:name="android.support.PARENT_ACTIVITY"        android:value=".MainActivity" />//想要返回的activity</activity>

在上述代码中我们明确在SecondActivity中点击导航按钮会返回到我们MainActivity中。
当然很多时候进入该activity的父activity是不确定的,因此我们可以重写getParentActivityIntent ()方法进行不同activity的跳转。

@Overridepublic Intent getParentActivityIntent() {//常见的方式是通过获取getIntent传递过来的Intent中携带的数据//根据该数据判断其对应的activity,之后创建新的intent指向该activity   return intent;}

返回的Intent就是我们点击后会实现的意图。这里我没有给出具体的代码,只是给出了实现的逻辑。因为实现的方法每个人都不同,但都很简单。
在测试这段代码时,无意间我发现一个很奇怪的事情

@Overridepublic Intent getParentActivityIntent() {   Intent intent=new Intent();   intent.setComponent(new ComponentName("aa","aa"));   return intent;}

通过setComponent,无论我填写的ComponentName的数据是什么,点击都能成功返回到上一个activity。一直搞不懂,求大牛说明下原因。

由于导航按钮也是actionBar上的一个item,所以我们也可以在onOptionsItemSelected()中实现它的点击事件。

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {   switch (item.getItemId())   {      case android.R.id.home://对应的Id        //点击后要实现的代码         return true;      default:         return super.onOptionsItemSelected(item);   }}

③在overflow中显示Icon
在上面提到overflow中默认是不显示Icon的,我们可以通过以下方法显示icon

rivate void setOverflowIconVisiable(Menu menu)//通过反射机制{   if (menu.getClass().getSimpleName().equals("MenuBuilder")) {      try {         Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);         m.setAccessible(true);         m.invoke(menu, true);      } catch (Exception e) {      }   }}@Overridepublic boolean onMenuOpened(int featureId, Menu menu) {   if (menu!=null)   {      setOverflowIconVisiable(menu);   }   return super.onMenuOpened(featureId, menu);}

添加一个actionView

一个ActionView是一个组件,用来替换ActionBar中的actionButton,可以在不用切换Activity和 Fragment并且不更换actionBar的情况下实现一些丰富的功能。
直接上例子

<menu xmlns:android="http://schemas.android.com/apk/res/android">    <item android:id="@+id/action_search"          android:icon="@drawable/ic_action_search"          android:title="@string/action_search"         android:actionViewClass="android.support.v7.widget.SearchView"          android:showAsAction="ifRoom|collapseActionView"/>    <item android:id="@+id/action_setting"          android:title="@string/action_settings"          android:icon="@mipmap/ic_launcher"          android:showAsAction="never"/></menu>

这里写图片描述
这里写图片描述
这里写图片描述

在showAsAction中添加collapseActionView选项
collapseActionView:通常与ifRoom一起使用,只会在设置了actionViewClass才会生效,它的作用是将actionViewClass设置的actionView折叠进actionButton中,当我们点击该actionButton时会将actionView展开
actionViewClass:指定一个组件作为actionView
例子中添加的是一个SearchView,当然我们也可以添加一个Button

android:actionViewClass="android.widget.Button"

注意:当我们将一个actionView折叠进一个actionButton中,我们就不需要对该actionButton实现点击事件,即我们在onOptionsItemSelected()中不该对actionButton进行响应,这是因为当我们点击actionButton时,系统依然会调用onOptionsItemSelected()。

成功在actionBar上显示了actionView,我们就需要响应事件

//从menu中获取search的ItemMenuItem searchItem=menu.findItem(R.id.action_search);//再从Item中获取viewSearchView searchView=      (SearchView)searchItem.getActionView(); //得到view对象,之后想干什么就能干什么了

另外Android还实现了对actionView折叠和展开的监听

public boolean onCreateOptionsMenu(Menu menu) {   MenuInflater inflater=getMenuInflater();   inflater.inflate(R.menu.action_bar_menu,menu);   //从menu中获取search的Item   MenuItem searchItem=menu.findItem(R.id.action_search);   MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {      @Override      public boolean onMenuItemActionExpand(MenuItem item)       {         return true;//true,展开actionView      }      @Override     public boolean onMenuItemActionCollapse(MenuItem item)      {         return true;//true,折叠actionView      }   });   return super.onCreateOptionsMenu(menu);}

添加Action Provider

与actionView类似,actionProvider用一个自定义的layout来代替actionButton,不同于actionView的是,actionProvider控制所有的action的行为并且当我们点击actionProvider会弹出子菜单。

我们可以通过继承ActionProvider类来自定义一个actionProvider。也可以使用android本身个给我们提供的一些actionProvider例如ShareActionProvider(实现分享)。

item android:id="@+id/action_share"      android:title="@string/share"      android:showAsAction="ifRoom"      tools:ignore="AppCompatResource"   android:actionProviderClass="android.widget.ShareActionProvider"    />

这时我们运行程序会发现多了个分享的button,当我们点击会发现并没有出现子菜单,这是因为我们还没定义子菜单中显示的内容。
在onCreateOptionMenu()中添加如下代码

MenuItem shareItem = menu.findItem(R.id.action_share);ShareActionProvider mShareActionProvider = (ShareActionProvider)shareItem.getActionProvider();mShareActionProvider.setShareIntent(getDefaultIntent());
private Intent getDefaultIntent() {   Intent intent = new Intent(Intent.ACTION_SEND);   intent.setType("image/*");   return intent;}

这里写图片描述

这里写图片描述

当我们点击子菜单中的Item后,会跳转到相应的界面。
除了使用ShareActionProvider之外,我们当然也可以自定义一个Action Provider,实现我们想要的功能。

public class MyActionProvider extends ActionProvider{   private Context mContext;   public MyActionProvider(Context context) {      super(context);      this.mContext=context;   }   @Override   public View onCreateActionView() {      LayoutInflater inflater=LayoutInflater.from(mContext);      View view=inflater.inflate(R.layout.action_provider, null);      Button btn= (Button) view.findViewById(R.id.button);      btn.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {              Toast.makeText(mContext,              "click",Toast.LENGTH_SHORT).show();         }      });      return view;   }}

这里写图片描述

发现actionbar上多了一个按钮,当我们点击的该button时,发现并没有像ShareActionProvider一样弹出一个子菜单(这时候跟actionButton的作用很像)。
想要实现子菜单的弹出,可以这样写

@Overridepublic View onCreateActionView() {   return null;//必须返回一个null,不然不会弹出子菜单}//必须重写该方法并返回true@Overridepublic boolean hasSubMenu() {   return true;}@Overridepublic void onPrepareSubMenu(SubMenu subMenu) {   subMenu.clear();   subMenu.add(0, 0, 0, "menu1")  .setIcon(R.mipmap.ic_launcher)  .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {      @Override      public boolean onMenuItemClick(MenuItem item) {         Toast.makeText(mContext, "submenu1",    Toast.LENGTH_SHORT).show();         return true;      }   });   subMenu.add(0, 1, 1,"menu2")  .setIcon(R.mipmap.ic_launcher)  .setOnMenuItemClickListener(  new MenuItem.OnMenuItemClickListener() {      @Override      public boolean onMenuItemClick(MenuItem item) {         Toast.makeText(mContext, "submenu", Toast.LENGTH_SHORT).show();         return true;      }   });}

点击,发现出现了子菜单。
这里写图片描述

至此,我们可以成功的实现一个完整的actionBar,当然actionBar还提供了Tab导航和下拉式导航,这里就不叙述了(主要是我没用过,也没看见哪个app有用过,现在导航好像都是通过viewPager实现的,有需要的可以看官方文档)
提示:在写代码的时候,千万不能导错包

通过上面的方法创建的actionBar太过单一,我们也可以通过自定义actionBar,来实现我们想要的actionBar的样式

自定义actionBar

自定义actionBar的方式有很多,android本身提供了两种基本的activity主题。
Theme.Holo :一种”dark”的主题
这里写图片描述
Theme.Holo.Light:一种”light”的主题
这里写图片描述

我们也可以通过改变各种参数,实现不同的风格

<style name="MyStyle" parent="@android:style/Theme.Holo.Light"><item   name="android:actionBarStyle">@style/MyActionBarStyle</item><item name="android:actionButtonStyle">@style/MyActionButtonStyle</item><item name="android:actionOverflowButtonStyle">@style/MyActionBarStyleOverflow</item></style>

actionBarStyle:
Baskground:设置actionBar的背景

<style name="MyActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar">    <item name="android:background">@color/orange</item></style>

这里写图片描述

ActionButtonStyle:设置actionButtonStyle的样式

<style name="MyActionButtonStyle"parent="@android:style/Widget.ActionButton">    <item name="android:background">@color/green</item></style>

这里写图片描述

ActionOverflowButtonStyle:设置actionOverflowButtonStyle的样式

<style name="MyActionBarStyleOverflow" parent="@android:style/Widget.ActionButton.Overflow">    <item name="android:src">@mipmap/ic_launcher</item></style>

这里写图片描述

TitleTextStyle:actionBar title的样式

<style name="MyActionBarTitleStyle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title">    <item name="android:textColor">@color/white</item></style><style name="MyActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar">    <item name="android:background">@color/orange</item>    <item name="android:titleTextStyle">@style/MyActionBarTitleStyle    </item></style>

这里写图片描述

这里我只是举了几个例子,关于样式的自定义还有很多,有兴趣的可以查询官方文档。

好了,到了这里关于actionBar的解析也就到了这里,当然本人水平,有限里面的内容绝大部分来源于android的官方文档,当然其中也有自己的一些理解。
在上面的内容中有一小部分内容也是第一次接触到,可能写的不是很准确,欢迎大家指出错误。
第一次写博客,花了很多时间,从中也收获了很多,希望自己能一直坚持下去(第一次多英文文档,有点痛苦,不过看着看着就习惯了,算是一种进步吧)

0 0