ActionBar 活动条
ActionBar是Android3.0重要更新之一,位于传统标题栏的位置(即屏幕顶部);可显示应用的图标和Activity的标题,此外ActionBar右边可显示活动项(Action item)
ActionBar的功能归纳如下:
.显示选项菜单的菜单项(将菜单项显示成Action Item)
.使用程序图标作为返回Home主屏或向上的导航操作
.提供交互式View作为Action View
.提供基于Tab的导航方式,可用于切换多个Fragment
.提供基于下拉的导航方式
一、启用ActionBar
最新的Android版本已经默认启用了ActionBar,因此只要在AndroidManifest.xml文件的sdk配置中指定该应用的目标版本高于11(Android3.0版本号),默认就会启用ActionBar;如果希望关闭ActionBar,则可以设置该应用的主题为Xxx.NoActionBar。
在实际应用中通常推荐使用代码来控制ActionBar的显示与隐藏:
show() 显示ActionBar
hide() 隐藏ActionBar
代码示例:
MainActivity.java
import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
ActionBar actionBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* 获取该Activity的ActionBar,只有当应用主题没有关闭ActionBar时该代码才返回ActionBar
* */
actionBar=getActionBar();
}
//为“显示ActionBar”按钮定义事件处理方法
public void showActionBar(View Source) {
//显示ActionBar
actionBar.show();
}
//为“隐藏ActionBar”按钮定义事件处理方法
public void hideActionBar(View Source) {
//隐藏ActionBar
actionBar.hide();
}
}
布局文件只有两个简单的按钮此处不予展示
运行结果如下:
二、使用ActionBar显示选项菜单项
从Android3.0开始,MenuItem增加了如下方法:
setShowAsAction(int actionEnum) 设置是否将菜单项显示在ActionBar上作为Action Item.
该方法支持如下参数:
SHOW_AS_ACTION_ALWAYS:总是将Item显示在ActionBar上;
SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW:将Action View折叠成普通的菜单项
SHOW_AS_ACTION_IF_ROOM:当ActionBar位置足够时才显示MenuItem;
SHOW_AS_ACTION_NEVER:不将MenuItem显示在ActionBar上
SHOW_AS_ACTION_WITH_TEXT:将MenuItem显示在ActionBar上,并显示该菜单项的文本。
实际项目中推荐件使用xml资源文件定义菜单,因此可以在xml菜单资源文件中为<item.../>元素指定如下属性:
android:showAsAction: 该属性的作用类似于setShowAsAction(int actionEnum)方法,因此该属性也能支持类似于上面的属性值。
本示例代码同android- 菜单 代码一致,不同的是在menu_main.xml文件的每个<item.../>元素增加了android:showAsAction属性,本次实验添加的代码如下:android:showAsAction="always|withText"
未添加运行结果:
添加后:
注意:手机顶部的ActionBar的空间是有限的,当选项菜单的菜单项很多时ActionBar无法同时显示所有的菜单项,Android会根据不同的手机采取不同的行为,对于没有MENU按键的手机ActionBar会在最后显示一个折叠图标,用户单击该图标就会显示剩余的选项菜单项。
三、启用程序图标导航
为了将应用程序图标转变成可以点击的图标,可以调用ActionBar的如下方法:
setDisplayHomeAsUpEnabled(boolean showHomeAsUp) :设置是否将应用程序图标转变成可点击的图标,并在图标上添加一个向左的箭头。
setDisplayOptions(int options) : 通过传入int类型常量来控制该ActionBar的显示选项。
setDisplayShowHomeEnabled(boolean showHome):设置是否显示应用程序的图标。
setHomeButtonEnabled(boolean enabled):设置是否将应用程序图标转变成可点击的按钮。
待续.....
四、添加Action View
ActionBar上除了可以使用普通的Action Item之外,还可以显示普通的UI组件;为了在ActionBar上添加Action View可采用如下两种方式:
.定义Action Item时使用android:actionViewClass属性指定Action View的实现类。
.定义Action Item时使用android:actionLayout属性指定ActionView对应的视图资源。
源代码示例:
menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/search"
android:title=""
android:orderInCategory="100"
android:showAsAction="always"
android:actionViewClass="android.widget.SearchView"
/>
<item
android:id="@+id/progress"
android:title=""
android:orderInCategory="100"
android:showAsAction="always"
android:actionLayout="@layout/clock"
/>
</menu>
上面粗体代码对应的布局资源文件如下:
clock.xml
<?xml version="1.0" encoding="utf-8"?>
<AnalogClock xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</AnalogClock>
运行结果:
五、使用ActionBar 实现Tab导航
ActionBar在顶端生成多个Tab标签,当用户点击某个Tab图标时系统根据用户点击事件导航到指定的Tab页面。
可按如下步骤:
.调用ActionBar的 setNavigationMode(ActionBar.NAVIGATION_MODE_TABS)方法设置使用Tab导航方式。
.调用ActionBar的addTab()方法添加多个Tab标签,并未每个Tab标签添加事件监听器。
(实际项目中为了更好的展现Tab导航效果,ActionBar通常会与Fragment结合使用)
代码示例:
布局文件main.xml,其中只定义了一个LinearLayout作为容器,接下来Activity将会使用该容器动态的盛装Fragment,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:id="@+id/container" >
</LinearLayout>
MainActivity.java
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
public class MainActivity extends Activity implements TabListener{
private static final String SELECTED_ITEM="selected_item";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ActionBar actionBar=getActionBar();
//设置ActionBar的导航方式,Tab导航
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//依次添加三个Tab标签,并为三个Tab标签添加事件监听器
actionBar.addTab(actionBar.newTab().setText("第一页").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第二页").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("第三页").setTabListener(this));
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.containsKey(SELECTED_ITEM)) {
//选中前面保存的索引对应的Fragment页
getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(SELECTED_ITEM));
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
//将当前选中的Fragment页的索引保存到Bundle中
outState.putInt(SELECTED_ITEM, getActionBar().getSelectedNavigationIndex());
}
// 当指定Tab标签被选中时激发该方法
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// 创建一个新的Fragment对象
Fragment fragment=new DummyFragment();
//创建一个新的对象,用于向Fragment传入参数
Bundle args=new Bundle();
args.putInt(DummyFragment.ARG_SECTION_NUMBER, tab.getPosition()+1);
//向Fragment传入参数
fragment.setArguments(args);
//获取FragmentTransaction对象
FragmentTransaction ft1=getFragmentManager().beginTransaction();
//使用Fragmentent代替Activity中的container组件
ft1.replace(R.id.container, fragment);
//提交事务
ft1.commit();
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {}
}
DummyFragment.java
import android.app.Fragment;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class DummyFragment extends Fragment {
public static final String ARG_SECTION_NUMBER="selection_number";
//该方法的返回值就是该Fragment显示的View组件
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView=new TextView(getActivity());
textView.setGravity(Gravity.START);
//获取创建该Fragment时传入的参数Bundle
Bundle args=getArguments();
//设置TextView显示的文本‘
textView.setText(args.getInt(ARG_SECTION_NUMBER)+"");
textView.setTextSize(30);
//返回该TextView
return textView;
}
}
执行结果:
注意:Android5.0已经将ActionBar导航这种方式设计为过时的方式;推荐使用更通用的导航方式(即ActionBar上的图标导航)
六、使用ActionBar 实现下拉导航
使用ActionBar实现下拉式导航步骤:
.调用ActionBar的actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST)方法设置使用下拉列表的导航方式。
.调用ActionBar的setListNavigationCallbacks(SpinnerAdapter adapter,ActionBar.OnNavigationListener callback)方法添加多个列表项,并为没个列表项添加事件监听器,第一个参数负责提供多个列表,第二个参数为事件监听器。
示例:
MainActivity.java
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.ActionBar.OnNavigationListener;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.widget.ArrayAdapter;
@SuppressLint("NewApi")
public class MainActivity extends Activity implements OnNavigationListener{
private static final String SELECTED_ITEM="selected_item";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ActionBar actionBar=getActionBar();
//设置ActionBar是否显示标题
actionBar.setDisplayShowTitleEnabled(true);
//设置导航模式,使用List导航
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
//为ActionBar安装ArrayAdapter
actionBar.setListNavigationCallbacks(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
android.R.id.text1,new String[]{"第一页","第二页","第三页"}),this);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.containsKey(SELECTED_ITEM)) {
//选中前面保存的索引对应的Fragment页
getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(SELECTED_ITEM));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
// 将当前选中的索引保存在Bundle中
outState.putInt(SELECTED_ITEM,getActionBar().getSelectedNavigationIndex());
}
//当导航项被选中时激发该方法
@Override
public boolean onNavigationItemSelected(int position, long id) {
// 创建一个新的Fragment对象
Fragment fragment=new DummyFragment();
//创建一个Bundle对象,用于向Fragment中传入参数
Bundle bundle=new Bundle();
bundle.putInt(DummyFragment.ARG_SECTION_NUMBER, position+1);
//向Fragment传入参数
fragment.setArguments(bundle);
//获取FragmentTransaction 对象
FragmentTransaction ft=getFragmentManager().beginTransaction();
//使用fragment代替Activity中container
ft.replace(R.id.container, fragment);
//提交事务】
ft.commit();
return true;
}
}
布局文件与Tab导航实例的布局文件相同;
运行结果: