首页 > 代码库 > 【Android UI设计与开发】之详解ActionBar的使用
【Android UI设计与开发】之详解ActionBar的使用
详解Android中的ActionBar的使用
请尊重他人的劳动成果,转载请注明出处:详解Android中的ActionBar的使用
http://blog.csdn.net/fengyuzhengfan/article/details/40216389
ActionBar是Android 3.0(API level 11)引入的一个新控件,它代表了应用程序标题栏,如果要开发兼容的程序,可以使用v7包下的ActionBar。我们在应用中看见的ActionBar一般是下图的样子,比如有道词典及微信:
1.App icon:应用的图标,左侧图标说明可以触摸返回,相当于触摸back返回键
2.ViewControl:下拉列表导航
3.Action button:相当于普通的Button可以监听点击事件
4.Action overflow:三个点,相当于手机上的menu键,可以显示隐藏的action button。
使用ActionBar一个最大好处是应用可以根据设备显示空间动态调整,如果显示空间不够,应用把多出的Action Button添加到Action overflow区域。
如何在应用中添加ActionBar
1、在应用中添加ActionBar,一般我们要继承ActionBarActivity:
public classMainActivity extends ActionBarActivity{ //……. }
也可以直接继承Activity,但是为了向后兼容,最好继承ActionBarActivity(注意这个类是兼容包v7中定义的)
2、在res/menu/目录中创建ActionBar的Item,如下:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="com.jph.ab.MainActivity"> <item android:id="@+id/refresh" android:orderInCategory="100" android:title="/刷新" android:icon="@drawable/ic_navigation_refresh" app:showAsAction="always"/> <item android:id="@+id/cancle" android:orderInCategory="100" android:title="取消" android:icon="@drawable/ic_navigation_cancel" app:showAsAction="always"/> <item android:id="@+id/setting" android:orderInCategory="100" android:title="设置" android:icon="@drawable/ic_action_settings" app:showAsAction="ifRoom"/> <item android:id="@+id/cancle2" android:orderInCategory="100" android:title="删除" android:icon="@drawable/ic_cab_done_holo" app:showAsAction="ifRoom"/> <item android:id="@+id/play" android:orderInCategory="100" android:title="播放" android:icon="@drawable/ic_media_play" app:showAsAction="never"/> </menu>
Menu标签中Item标签的主要属性:
属性名 | 解释 |
android:orderInCategory | 表示每个item的优先级,值越大优先级越低,actionbar地方不够就会放到overflow中。 |
android:title | item的标题。 |
android:icon | item显示的图标。 |
app:showAsAction | item显示的方式。 |
其showAsAction属性接受如下一些值:
ifRoom | 会显示在Item中,但是如果已经有4个或者4个以上的Item时会隐藏在溢出列表中。当然个数并不仅仅局限于4个,依据屏幕的宽窄而定 |
never | 永远不会显示。只会在溢出列表中显示,而且只显示标题,所以在定义item的时候,最好把标题都带上。 |
always | 无论是否溢出,总会显示。 |
withText | withText值示意Action bar要显示文本标题。Action bar会尽可能的显示这个标题,但是,如果图标有效并且受到Action bar空间的限制,文本标题有可能显示不全。 |
collapseActionView | 声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。否则,这个操作视窗在默认的情况下是不可见的。一般要配合ifRoom一起使用才会有效果。 |
提示:为了兼容低版本,这里没有使用android:showAsAction而是使用的v7兼容包中的app:showAsAction。使用app:showAsAction需要将 xmlns:app=http://schemas.android.com/apk/res-auto命名空间导进来。
3、重写ActionBarActivity中的方式:
@Override public booleanonCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to theaction bar if it is present. getMenuInflater().inflate(R.menu.simple, menu);//获取menu目录下simple.xml的菜单文件 return true; }
这时ActionBar的Item在应用中就能够显示了,如果要让触摸Item添加功能,必须重写进行第4步
4、监听触摸Item事件
@Override public booleanonOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id) { case R.id.refresh: Utils.showToast(this, "您点击了刷新菜单", Toast.LENGTH_SHORT); return true; case R.id.cancle: Utils.showToast(this, "您点击了取消菜单", Toast.LENGTH_SHORT); return true; case R.id.cancle2: Utils.showToast(this, "您点击了删除菜单", Toast.LENGTH_SHORT); return true; case R.id.setting: Utils.showToast(this, "您点击了设置菜单", Toast.LENGTH_SHORT); return true; case R.id.play: Utils.showToast(this, "您点击了播放菜单", Toast.LENGTH_SHORT); return true; } return super.onOptionsItemSelected(item); }
程序运行效果图:
为ActionBar配置返回键
在AndroidManifest.xml中为需要返回到上一级的activity配置android:parentActivityName=".MainActivity"属性。其中parentActivityName表示当前activity要返回到activity。
<activity android:name=".SpinnerActionBar" android:parentActivityName=".MainActivity" android:label="ActionBar实现下拉导航"></activity>
程序运行效果图:
显示溢出区按钮
如果手机有menu键ActionBar可能不会显示三个点的溢出按钮,触摸菜单键才会显示ActionBar overflow区域,这样用户体验不一致,为了能够让有菜单键的设备,也能够显示溢出按钮,则需要加入以下代码:
/** * 即使有物理菜单键也显示ActionBar的flowMenu */ public static void showOverflowMenu(Context context) { try { ViewConfiguration config = ViewConfiguration.get(context); //使用java反射技术,获取getDeclaredField类的私有属性sHasPermanentMenuKey Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); if(menuKeyField != null){ menuKeyField.setAccessible(true); //将属性设为可访问的 menuKeyField.setBoolean(config, false); //为属性赋值为false } } catch (Exception e) { e.printStackTrace(); } }
然后,在onCreate中调用这个函数,这样有菜单键的设备就能显示溢出按钮了。
ActionBar实现下拉导航
具体步骤:
l 首先需要一个SpinnerAdapter设置下拉item的内容和显示的layout
l 实现ActionBar.OnNavigationListener这个接口,接口中有点击item的事件
l 设置navigationmode例如
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
l 用setListNavigationCallbacks()方法来实现下拉选项,例如
actionBar.setListNavigationCallbacks(mSpinnerAdapter,mNavigationCallback);
程序代码:
package com.jph.ab.activity; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar.OnNavigationListener; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.widget.ArrayAdapter; import android.widget.Toast; import com.jph.ab.utils.Utils; /** * ActionBar实现下拉导航 * @author jph * Date:2014.10.13 */ public class SpinnerActionBar extends ActionBarActivity { private ActionBar actionbar; /**菜单名称***/ private String[] menuItems; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); Utils.showOverflowMenu(this);//如果手机有menu键也显示flowMenu actionbar=getSupportActionBar();//获取v7兼容包中的ActionBar actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); menuItems=getResources().getStringArray(R.array.menus);//获取string_array.xml中的menus数组 ArrayAdapter<String> adapter=new ArrayAdapter<String>(this, R.layout.spinner,R.id.tvMenu,menuItems ); actionbar.setListNavigationCallbacks(adapter, new OnNavigationListener() { @Override public boolean onNavigationItemSelected(int itemPosition, long itemId) { // TODO Auto-generated method stub Utils.showToast(SpinnerActionBar.this,"您选择了:"+ menuItems[itemPosition],Toast.LENGTH_SHORT); return true; } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.simple, menu);//获取menu目录下simple.xml的菜单文件 return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); switch (id) { case R.id.refresh: Utils.showToast(this, "您点击了刷新菜单", Toast.LENGTH_SHORT); return true; case R.id.cancle: Utils.showToast(this, "您点击了取消菜单", Toast.LENGTH_SHORT); return true; case R.id.cancle2: Utils.showToast(this, "您点击了删除菜单", Toast.LENGTH_SHORT); return true; case R.id.setting: Utils.showToast(this, "您点击了设置菜单", Toast.LENGTH_SHORT); return true; case R.id.play: Utils.showToast(this, "您点击了播放菜单", Toast.LENGTH_SHORT); return true; } return super.onOptionsItemSelected(item); } }
程序运行效果图:
ActionBar实现Tab导航
package com.jph.ab.activity; import java.util.ArrayList; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar.Tab; import android.support.v7.app.ActionBar.TabListener; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import com.jph.ab.fragment.BaseFragment; import com.jph.ab.fragment.BaseFragmentPagerAdapter; import com.jph.ab.utils.Utils; /** * ActionBar实现Tab导航 * 程序亮点:ActionBar Tab+ViewPager+Fragment * @author jph * Date:2014.10.13 */ public class TabActionBar extends ActionBarActivity { private ActionBar actionbar; private ViewPager vpContent; /**ViewPager包含的Fragment集合**/ private ArrayList<Fragment> fragments; /**ActionBar上的Tab集合**/ private ArrayList<Tab> tabs; /**当前页**/ protected int currentPage; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.tab_actionbar); Utils.showOverflowMenu(this);//如果手机有menu键也显示flowMenu initViewPager();//初始化ViewPager要在初始化initTab之前,否则会出错 initTab(); } /** * 初始化Tab */ private void initTab() { // TODO Auto-generated method stub tabs=new ArrayList<Tab>(); actionbar=getSupportActionBar();//获取v7兼容包中的ActionBar actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); Tab tabMyContacts=actionbar.newTab();//创建一个tab实例 Tab tabMyFavorite=actionbar.newTab(); tabMyContacts.setTag(0);//为Tab设置Tag,用于标识Tab的位置 tabMyContacts.setText("全部联系人"); tabMyFavorite.setTag(1); tabMyFavorite.setText("常用联系人"); tabMyContacts.setTabListener(tabListener);//为Tab设置监听(这一步是必须的,不然系统会不报错) tabMyFavorite.setTabListener(tabListener); tabs.add(tabMyContacts); tabs.add(tabMyFavorite); actionbar.addTab(tabMyContacts);//将Tab添加ActionBar上 actionbar.addTab(tabMyFavorite); } /** * 初始化ViewPager */ private void initViewPager() { // TODO Auto-generated method stub vpContent=(ViewPager)findViewById(R.id.vpContent); //初始化ViewPager显示的页面集合 fragments = new ArrayList<Fragment>(); BaseFragment fragment1=BaseFragment.newInstance(BaseFragment.LOAD_FRAGMENT_1); BaseFragment fragment2=BaseFragment.newInstance(BaseFragment.LOAD_FRAGMENT_2); fragments.add(fragment1); fragments.add(fragment2); //设置ViewPager adapter BaseFragmentPagerAdapter adapter=new BaseFragmentPagerAdapter(getSupportFragmentManager(), fragments); vpContent.setAdapter(adapter); vpContent.setCurrentItem(0);//默认显示第一个页面 //监听ViewPager事件 vpContent.setOnPageChangeListener(new OnPageChangeListener(){ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { currentPage = position; actionbar.selectTab(tabs.get(position));//当滑动页面结束让ActionBar选择指定的Tab } @Override public void onPageScrollStateChanged(int state) { } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.simple, menu);//获取menu目录下simple.xml的菜单文件 return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); switch (id) { case R.id.refresh: Utils.showToast(this, "您点击了刷新菜单", Toast.LENGTH_SHORT); return true; } return super.onOptionsItemSelected(item); } /** * ActionBar的Tab监听器 */ TabListener tabListener=new TabListener() { @Override public void onTabUnselected(Tab arg0, FragmentTransaction arg1) { // TODO Auto-generated method stub } @Override public void onTabSelected(Tab selectedTab, FragmentTransaction arg1) { // TODO Auto-generated method stub vpContent.setCurrentItem((Integer) selectedTab.getTag());//当选中了指定的Tab后让VeiwPager滑动到指定页面 } @Override public void onTabReselected(Tab arg0, FragmentTransaction arg1) { // TODO Auto-generated method stub } }; }
程序运行效果图:
ActionBar实现分享
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="com.jph.ab.MainActivity"> <!-- 分享 --> <item android:id="@+id/share" android:title="分享" app:actionProviderClass="android.support.v7.widget.ShareActionProvider" app:showAsAction="always" /> </menu>
package com.jph.ab.activity; import com.jph.ab.utils.Utils; import android.content.Intent; import android.os.Bundle; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.ShareActionProvider; import android.view.Menu; import android.view.MenuItem; /** * ActionBar实现分享 * @author jph * Date:2014.10.13 */ public class ShareActionBar extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); Utils.showOverflowMenu(this);//如果手机有menu键也显示flowMenu } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.share, menu);//获取menu目录下simple.xml的菜单文件 setShare(menu); return true; } /** * 为ActionBar实现分享 * @param menu */ private void setShare(Menu menu) { // TODO Auto-generated method stub MenuItem item = menu.findItem(R.id.share); ShareActionProvider sap = (ShareActionProvider) MenuItemCompat .getActionProvider(item); Intent shareIntent = new Intent(); shareIntent.setType("text/plain"); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.putExtra(Intent.EXTRA_TEXT, "ActionBar实现分享@author:jph"); sap.setShareIntent(shareIntent); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. return super.onOptionsItemSelected(item); } }
程序运行效果图:
ActionBar实现搜索(操作视图)
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context="com.jph.ab.MainActivity"> <item android:id="@+id/search" android:orderInCategory="100" android:title="搜索" app:actionViewClass="android.support.v7.widget.SearchView" android:icon="@drawable/abc_ic_search" app:showAsAction="collapseActionView|ifRoom" /> <item android:id="@+id/cancle" android:orderInCategory="100" android:title="取消" android:icon="@drawable/ic_navigation_cancel"/> </menu>
package com.jph.ab.activity; import com.jph.ab.utils.Utils; import android.os.Bundle; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView.OnQueryTextListener; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; /** * ActionBar实现搜索 * @author jph * Date:2014.10.13 */ public class SearchActionBar extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); Utils.showOverflowMenu(this);//如果手机有menu键也显示flowMenu } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.search, menu);//获取menu目录下simple.xml的菜单文件 setSearch(menu); return true; } /** * 为ActionBar实现查询功能 * @param menu */ private void setSearch(Menu menu) { // TODO Auto-generated method stub final MenuItem item = menu.findItem(R.id.search); SearchView sv = (SearchView) MenuItemCompat.getActionView(item); if(sv != null){ sv.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String arg0) { Utils.showToast(SearchActionBar.this, arg0, Toast.LENGTH_SHORT); MenuItemCompat.collapseActionView(item); return true; } @Override public boolean onQueryTextChange(String arg0) { return false; } }); } } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); switch (id) { case R.id.cancle: Utils.showToast(this, "您点击了取消菜单", Toast.LENGTH_SHORT); return true; } return super.onOptionsItemSelected(item); } }
程序运行效果图:
如果你觉得这篇博文对你有帮助的话,请为这篇博文点个赞吧!也可以关注fengyuzhengfan的博客,收看更多精彩!http://blog.csdn.net/fengyuzhengfan/
【Android UI设计与开发】之详解ActionBar的使用