Actionbar

  请尊重他人的劳动成果,转载请注明出处: 详解Android中的ActionBar的使用 

http://blog.csdn.net/fengyuzhengfan/article/details/40216389

ActionBar 是 Android 3.0(API level 11) 引入的一个新控件,它代表了应用程序标题栏,如果要开发兼容的程序,可以使用 v7 包下的ActionBar 。我们在应用中看见的 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

 ActionBar 配置返回键

 AndroidManifest.xml 中为需要返回到上一级的 activity 配置android:parentActivityName = ".MainActivity" 属性。其中parentActivityName 表示当前 activity 要返回到 activity 。

<activity android:name=".SpinnerActionBar"
            android:parentActivityName=".MainActivity"
            android:label="ActionBar实现下拉导航"></activity>

程序运行效果图:

为ActionBar配置返回键

显示溢出区按钮

如果手机有 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实现下拉导航

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实现Tab导航

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实现分享

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);
  }
}

程序运行效果图:

ActionBar实现搜索(操作视图)

如果你觉得这篇博文对你有帮助的话,请为这篇博文点个赞吧!也可以关注fengyuzhengfan的博客,收看更多精彩!http://blog.csdn.net/fengyuzhengfan/    

posted @ 2016-01-28 04:28  crazy_machine  阅读(166)  评论(0)    收藏  举报