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); } }
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); }
<item android:id="@+id/action_search" android:actionViewClass="android.widget.SearchView" android:showAsAction="always" android:title="@string/action_alarm"/>
可以为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,并参阅部分博客后写的学习笔记,如有不足/有误之处欢迎留言指出,谢谢!