您的位置:首页 > 移动开发 > Android开发

Android ActionBar应用一:ActionBar返回任意页面和顶部搜索栏实现

2015-04-07 19:28 375 查看
转载请注明出处:/article/1534358.html

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里,再去做真正的搜索操作,查询数据库或者搜索网络等等。。。

下面把返回功能和搜索放到一起,效果如图:



转载请注明出处:/article/1534358.html

源码下载:http://download.csdn.net/detail/cyp331203/8571823
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐