转载请注明出处:http://blog.csdn.net/cyp331203/article/details/44922863
Action Bar是app应用顶部的一个方形区域,不一定总会显示(如全屏Theme时),它属于窗口的一部分,有点类似于windows的窗口的标题栏,如下图所示:
ActionBar简要介绍:
如上图所示,标题栏一般会有三类按钮:
1、可以称为home区,这里有一个标识app的按钮,这个按钮默认不被激活,图片显示默认跟app的图标一致
2、可以称为按钮区,显示在按钮区的多个标题栏按钮
3、“更多”按钮,点击可以下拉出隐藏的标题栏按钮,俗称:"overflow"
需要明确的一点是:
ActionBar的API最早是在Android 3.0(API Level 11)的时候加入Android中的,但是我们也可以在Android 2.1(API Level 7)以上的版本使用它,只是需要加入支持包,也就是通常说的 v4
support library和 v7
support library
一般来说,为了兼容性考虑,在写应用的时候,都会使用兼容性包里的ActionBar相关API,而不会去使用系统自带的,所以后面的部分默认都是基于V4和V7包中的内容来介绍。
在导入要使用兼容性包中的ActionBar,我们的MainActivity或者其他XxxActivity就不能在继承自Activity了,需要换成:ActionBarActivity,然后还需要在清单文件中,换成AppCompat主题或者其子主题,关于主题可以看这一篇ActionBar主题颜色:
拿到ActionBar对象:
public class MainActivity extends ActionBarActivity <activity android:theme="@style/Theme.AppCompat.Light" ... >
然后,可以通过下面一句代码,拿到ActionBar的对象:
ActionBar mActionBar = getSupportActionBar();
然后可以调用下面两句,让整个actionBar显示或者隐藏:
mActionBar.hide(); mActionBar.show();
激活home区按钮:
但是单单是拿到这个对象,并没什么用,还是不能点击,需要做进一步处理,这里类似于Button的使能设置,setEnable:
mActionBar.setHomeButtonEnabled(true); mActionBar.setDisplayShowHomeEnabled(true);//这两句就可以让actionBar的图标可以响应点击事件 mActionBar.setDisplayHomeAsUpEnabled(true);//这一句主要用于后面返回效果,后面会讲
设置按钮区:
上面的按钮区,则需要使用一个表示menu的xml文件,一般存放在res/menu/下,然后重写onCreateOptionsMenu()方法来设置,res/menu/main_activity_actions.xml文件如下:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:alex="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/action_search" alex:showAsAction="collapseActionView|ifRoom|withText" android:icon="@drawable/ic_action_search" android:title="搜索"/> <item android:id="@+id/action_share" alex:showAsAction="collapseActionView|ifRoom|withText" android:icon="@drawable/ic_action_share" android:title="分享"/> <item android:id="@+id/action_search2" alex:actionViewClass="android.support.v7.widget.SearchView" alex:showAsAction="collapseActionView|ifRoom|withText" android:icon="@drawable/ic_action_search" android:title="搜索"/> <item android:id="@+id/action_share2" alex:showAsAction="collapseActionView|ifRoom|withText" android:icon="@drawable/ic_action_share" android:title="分享"/> <item android:id="@+id/action_hide" alex:showAsAction="collapseActionView|ifRoom|withText" android:icon="@drawable/ic_action_share" android:title="隐藏的按钮"/> </menu>
看到上面使用了一个自定义属性:showAsAction,这个属性用于表示按钮的显示方式一般常用的有:ifRoom(表示有空间就会显示出来),withText(表示带名字,但不一定会显示,一般会文字会显示在”更多“按钮下),never(从不直接显示在ActionBar上,意味着这个按钮一直会显示在”更多“按钮的下拉菜单上),要注意的是,”更多“按钮不一定会显示,如果没有足够的空间或者有never属性的按钮,则会显示,否则不会显示。stackoverflow上有研究过怎么让更多一直显示,感兴趣可以看看:http://stackoverflow.com/questions/20444596/how-to-force-action-bar-overflow-icon-to-show
除此之外,上面的xml中还制定了按钮的id和图片和title属性。
然后,可以通过重写 onCreateOptionsMenu()
方法来让这些图标都显示出来:
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu items for use in the action bar MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_activity_actions, menu); return super.onCreateOptionsMenu(menu); }
处理点击事件:
通过重写onOptionsItemSelected()方法可以达到目的,但是需要注意的一点是,对于ActionBar图标,也就是那个app的图标,它的id是:android.R.id.home。
@Override public boolean onOptionsItemSelected(MenuItem item) { int itemId = item.getItemId(); switch (itemId) { case android.R.id.home: Toast.makeText(this, "home", 0).show(); break; case R.id.action_search: Toast.makeText(this, "search", 0).show(); break; default: Toast.makeText(this, "itemId=" + itemId, 1).show(); break; } return super.onOptionsItemSelected(item); }
完成上面的部分,就可以得到一个类似于下面的界面了
通过ActionBar实现返回上一个/任意制定的Activity的功能:
在写App的时候,经常会想需要这样一个功能,从任意一个Activity返回初始/首页的activity;这个功能可以很容易的使用ActionBar按钮来完成。
有两种实现方式:xml清单文件配置方式 和 java代码方式。
两种方式都需要设置上面提到的一个属性:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_details); ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); ... }
方法一:xml清单文件配置方式实现返回:
假如两个Activity:A和B,B要返回A,则要在清单文件B的位置,以meta-data的方式,设置android.support.PARENT_ACTIVITY为A的全类名,如下面代码所示。
<application ... > ... <!-- The main/home activity (has no parent activity) --> <activity android:name="com.example.myfirstapp.ActivityA" ...> ... </activity> <!-- A child of the main activity --> <activity android:name="com.example.myfirstapp.ActivityB" android:label="@string/title_activity_display_message" android:parentActivityName="com.example.myfirstapp.MainActivity" > <!-- Parent activity meta-data to support API level 7+ --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.myfirstapp.ActivityA" /> </activity> </application>
然后,点击ActionBar的home键,就可以直接从ActivityB回到ActivityA了。
方法二:重写ActivityB中的 getSupportParentActivityIntent()
和 onCreateSupportNavigateUpTaskStack()
方法。
实际上这两种方法不一定都要重写,getSupportParentActivityIntent()用于本app内部的activity跳转,onCreateSupportNavigateUpTaskStack()用于跳转到其他app的activity,就比较复杂,这里不做讨论,可以查看http://developer.android.com/guide/topics/ui/actionbar.html#ActionViewCollapsing
getSupportParentActivityIntent()返回一个要跳转的Intent,所以这里只需要返回一个指向我们想要跳转到的Activity的Intent对象即可实现跳转。
相对而言,代码方式更加灵活。
值得注意的是,上述两种方法只能应用于Activity之间的跳转,如果想要应用于Fragment之间,需要使用 onSupportNavigateUp()
和popBackStack()方法。
Android搜索栏初探:
首先需要在上面的menu的xml文件中的对应item,比如上面的action_search所在的item中,添加一个自定义属性来为这个按钮添加一个SearchView:
<item android:id="@+id/action_search" alex:actionViewClass="android.support.v7.widget.SearchView" alex:showAsAction="collapseActionView|ifRoom|withText" android:icon="@drawable/ic_action_search" android:title="搜索"/>
然后需要在onCreateOptionsMenu方法中,把这个SearchView创建出来:
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_activity_actions, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); // Configure the search info and add any event listeners ... return super.onCreateOptionsMenu(menu); }
在添加了之后点击搜索按钮,就会有对应的搜索栏显示出来:
但是现在这样还不太爽。。。一没有搜索提示文字,二没有真正能搜索的功能,下面就来做这两步:
搜索提示文字(hint):
这里需要一个写一个searchable的xml文件到res/xml/文件夹下:
res/xml/searchable.xml
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:hint="@string/search_hint" android:label="@string/app_label" > </searchable>
上面是一个简单的searchable,实际上searchable的属性可以很多,但是大多数都用不上,除非需要语音搜索或者别的附加功能。
接下来,就要将这个searchable.xml与我们要展示搜索结果的那个activity在清单文件中关联起来,这里也需要使用到meta-data,注意这里位置是要显示搜索结果的那个activity,而不一定是当前activity:
<application ... > <activity android:name="com.example.actionbarex.SecondActivity" > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity> ... </application>
这里的android.app.searchable,代表搜索的属性,hint提示等,不能改;而@xml/searchable代表res/xml/searchable.xml文件
然后,我们还需要将搜索的输入框默认与对应的搜索activity挂钩,也要使用meta-data,但是需要在application内或者别的要搜索的activity内配置,这里以卸载application内为例:
<application ... > <meta-data android:name="android.app.default_searchable" android:value="com.example.actionbarex.SecondActivity" /> ... </application>
这里配置好之后,我们就要在这个要显示搜索结果的activity中的onCreate方法中,接收发来的Intent对象,然后判断这个Intent对象是不是要请求搜索:Intent.ACTION_SEARCH
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search); // Get the intent, verify the action and get the query Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doSearching(query); } }
private void doSearching(String query) { System.out.println("做一些搜索的耗时操作...."); }
经过上面的操作之后,就可以建立一个简单的搜索结构了,然后我们在doSearching里,再去做真正的搜索操作,查询数据库或者搜索网络等等。。。
下面把返回功能和搜索放到一起,效果如图:
转载请注明出处:http://blog.csdn.net/cyp331203/article/details/44922863