八、在ActionBar上添加导航tab
Tabs的应用可以算是非常广泛了,它可以使得用户非常轻松地在你的应用程序中切换不同的视图。而Android官方更加推荐使用ActionBar中提供的Tabs功能,因为它更加的智能,可以自动适配各种屏幕的大小。
为ActionBar添加导航tab主要有如下几步:
1. 获得ActionBar对象,并设置ActionBar的导航模式为tabs模式;
2. 创建需要显示在ActionBar上的tabs,并设置这些选项卡的title和icon,为tabs添加监听器;
3. 通过ActionBar的addTab方法将tab添加到ActionBar上;
首先,我创建了一个实现了ActionBar.TabListener接口的类,代码如下:
public class CustomTabListener<T extends Fragment> implements TabListener {
private Fragment mFragment;
private Activity mActivity;
private Class<T> mClass;
public CustomTabListener(Activity activity, Class<T> clz) {
mActivity = activity;
mClass = clz;
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Toast.makeText(mActivity, "Change tab", 3000).show();
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// ft.detach(mFragment);
}
}
然后在activity的onCreate方法中写了一个initView方法,方法内容为:
private void initView() {
// 获得ActionBar
ActionBar actionBar = getActionBar();
// 设置导航模式为选项卡模式
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// 创建三个选项卡
Tab nearTab = actionBar.newTab();
Tab shakeTab = actionBar.newTab();
Tab bootleTab = actionBar.newTab();
// 为三个选项卡设置文本和icon
nearTab.setText("Near").setIcon(R.drawable.near);
shakeTab.setText("Shake").setIcon(R.drawable.shake);
bootleTab.setText("Bootle").setIcon(R.drawable.bottle);
// 为三个选项卡添加监听器
nearTab.setTabListener(new CustomTabListener<NearFragment>(this,
NearFragment.class));
shakeTab.setTabListener(new CustomTabListener<ShakeFragment>(this,
ShakeFragment.class));
bootleTab.setTabListener(new CustomTabListener<BottleFragment>(this,
BottleFragment.class));
// 将三个选项卡添加到actionBar上
actionBar.addTab(nearTab);
actionBar.addTab(shakeTab);
actionBar.addTab(bootleTab);
}
这样就成功地将tab添加到ActionBar上了,效果如下:
点击某一个选项卡时,就会显示一次toast消息。
九、添加Action View
ActionView是一种可以在ActionBar中替换Action按钮的控件,它可以允许用户在不切换界面的情况下通过ActionBar完成一些较为丰富的操作。比如说,你需要完成一个搜索功能,就可以将SeachView这个控件添加到ActionBar中。
为了声明一个ActionView,我们可以在menu资源中通过actionViewClass属性来指定一个控件
<item
android:id="@+id/action_search"
android:actionViewClass="android.widget.SearchView"
android:showAsAction="always"
android:title="@string/action_alarm"/>
然后按照上面添加Action Button的步骤进行便可以将Action View添加到ActionBar上,效果如下(图一和图二分别表示Action View收起和展开时的样子):
可以为Action View添加响应事件,方法为重写onCreateOptionsMenu方法,在该方法中获得Action View对象,然后为该Action View对象添加OnActionExpandListener和onMenuItemActionCollapse监听器,这样当SearchView展开的时候就会回调onMenuItemActionExpand()方法,当SearchView合并的时候就会调用onMenuItemActionCollapse()方法,我们在这两个方法中进行相应的UI操作就可以了。
关于SearchView的更多详细用法,可以参考官方文档 http://developer.android.com/guide/topics/search/search-dialog.html。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_action_bar_02, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
// 为action view添加响应事件
searchItem.setOnActionExpandListener(new OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
Log.d(TAG, "on expand");
Toast.makeText(getApplicationContext(), "expand",
Toast.LENGTH_SHORT).show();
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
Log.d(TAG, "on collapse");
Toast.makeText(getApplicationContext(), "collapse",
Toast.LENGTH_SHORT).show();
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
十、overflow溢出菜单不显示
问题:在有些机器上overflow溢出菜单并不会显示
原因:Android系统默认首先会判断该机器是否有物理菜单键,如果有物理菜单键则不显示溢出菜单,将溢出菜单中的内容通过用户点击物理菜单键进行显示;如果没有物理菜单键则显示溢出菜单;
解决办法:如果想要然所有的机器均能够显示溢出菜单,可以通过如下方法实现
办法1:定义如下方法,然后在需要显示溢出菜单的activity的onCreate方法中调用该方法;
1. <!-- 强制显示overflow menu -->
2. private void getOverflowMenu() {
3. try {
4. ViewConfiguration config = ViewConfiguration.get(this);
5. Field menuKeyField = ViewConfiguration.class
6. .getDeclaredField("sHasPermanentMenuKey");
7. if (menuKeyField != null) {
8. menuKeyField.setAccessible(true);
9. menuKeyField.setBoolean(config, false);
10. }
11. } catch (Exception e) {
12. e.printStackTrace();
13. }
14. }
办法2:自定义一个Application如下,然后在AndroidManifest.xml中修改application的android:name=".UIApplication"(注意路径)这样在该应用的所有activity中都会显示overflow menu菜单。
注:该方法只针对Android 4.0以上系统有效,其余系统可以使用PopupWindow实现类似功能
1. public class UIApplication extends Applications{
2. public void onCreate() { try {
3. ViewConfiguration config = ViewConfiguration.get(this);
4. Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
5. if (menuKeyField != null) {
6. menuKeyField.setAccessible(true);
7. menuKeyField.setBoolean(config, false);
8. }
9. }
10. catch (Exception ex) {
11. // Ignore
12. }
13. super.onCreate();
14. }
15. }
原理:在ViewConfiguration这个类中有一个叫做sHasPermanentMenuKey的静态变量,系统就是根据这个变量的值来判断手机有没有物理Menu键的。因此我们可以通过修改该变量的值而使得系统认为此机器无物理菜单键,从而显示溢出菜单
十一、让overflow中的选项显示icon
问题:overflow中的选项只显示title,而不会显式icon
原因:这是Google官方的默认效果,Google认为隐藏在overflow中的Action按钮都应该只显示文字。
解决办法:其实,overflow中的Action按钮应不应该显示图标,是由MenuBuilder这个类的setOptionalIconsVisible变量来决定的,如果我们在overflow被展开的时候将这个变量赋值为true,那么里面的每一个Action按钮对应的图标就都会显示出来了。
代码如下:
/**
* 改变setOptionalIconsVisible的值,使得overflow能够显示icon
*/
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {
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) {
e.printStackTrace();
}
}
}
return super.onMenuOpened(featureId, menu);
}
效果如下:
以上便是本人这两天根据官方training学习ActionBar,并参阅部分博客后写的学习笔记,如有不足/有误之处欢迎留言指出,谢谢!
来源:oschina
链接:https://my.oschina.net/u/2621851/blog/618305