ActionBar 在android3.0中就加入了,但是android3.0适用于平板电脑的,在手机不能使用。android 4.0之后也开始有AndroidBar。所以说要想使用androidBar ,API级别至少是11级以上(当然如果API低于11也可以使用ActionBar,但是必须引入一个第三方的jar包,),如下图是我们在email中经常看到的,这个就是使用了ActionBar来设置的。

如何添加一个ActionBar

要在android4.0上添加actionBar很容易,只需要下面的两句:

private ActionBar actionBar;
actionBar=getActionBar();

只是一个getActionBar()就显示出了ActionBar,在使用的过程中要想隐藏ActionBar如下;

private ActionBar actionBar;
actionBar=getActionBar();
actionBar.hide();

 

ActionBar的组成部分

这个图片是从官网上面抓取过来的,从这个图片中很容易就看出ActionBar分三部分

(1)APP Icon 

就是一导航的logo,这个分为图片和文字,当然如果我们不想使用它也可以在代码中隐藏掉

        private ActionBar actionBar;
        actionBar=getActionBar();
        //setDisplayShowTitleEnabled隐藏导航的标题
        actionBar.setDisplayShowTitleEnabled(false);
        //setDisplayShowHomeEnabled隐藏导航的图标
        actionBar.setDisplayShowHomeEnabled(false);

(2)Action Item

每一个Action Item包括一个图标和标题,那么如何来添加一个Action Item呢?这个和添加menu有点相似,也是需要在res目录中添加menu文件夹,如下图:

我们这里添加了gmail.xml文件,我们再来看看这个文件里的代码是如何写的

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_email"
        android:icon="@drawable/ic_menu_compose_normal_holo_light"
        android:showAsAction="ifRoom|withText"
        android:title="Email"/>
    <item
        android:id="@+id/menu_search"
        android:actionLayout="@layout/collapsibleview"
        android:icon="@drawable/ic_menu_search_holo_light"
        android:showAsAction="collapseActionView|ifRoom"
        android:title="Search"/>
    <item
        android:id="@+id/menu_folders"
        android:icon="@drawable/ic_menu_folders_holo_light"
        android:showAsAction="ifRoom|withText"
        android:title="Folders"/>
    <item
        android:id="@+id/menu_refresh"
        android:icon="@drawable/ic_menu_refresh_holo_light"
        android:showAsAction="ifRoom|withText"
        android:title="Refresh"/>
    <item
        android:id="@+id/menu_archive"
        android:icon="@drawable/ic_menu_archive_holo_light"
        android:showAsAction="never"
        android:title="Archive"/>

</menu>

上面就是添加的Action item 每一个item标签是一个ActionBar Item ,这个item中id属性,这个属性就不用我来介绍了吧。android:icon是这个item的图标,android:titles是这个item的文本显示,那么这个android:showAsAction是什么呢?我们放到后面再来介绍,在添加好相应的xml文件之后再在代码onCreateOptionsMenu类中加载xml文件,如下代码

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.gmail, menu);
        return true;
    }

加上之后直接跑程序就可以看到你设置的效果了,那么如何设置点击事件呢?很容易,直接看代码:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub
        switch(item.getItemId()){
        case R.id.menu_email:{
            Toast.makeText(this, "OKOKO", Toast.LENGTH_LONG).show();
            break;
        }
        }
        return super.onOptionsItemSelected(item);
    }

(3)溢出菜单

从图片看到这个是一个隐式的菜单,系统是用三个点来表示,也可以叫做Action overflow ,这个主要是由于Action item过多导致没有足够的空间来存放Action item之后而需要把一些移到action overflow里面,这个里面就涉及到Android:showAsAction属性的设置,来看下面这段代码

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_email"
        android:icon="@drawable/ic_menu_compose_normal_holo_light"
        android:showAsAction="ifRoom|withText"
        android:title="Email"/>
    <item
        android:id="@+id/menu_search"
        android:actionLayout="@layout/collapsibleview"
        android:icon="@drawable/ic_menu_search_holo_light"
        android:showAsAction="collapseActionView|ifRoom"
        android:title="Search"/>
    <item
        android:id="@+id/menu_folders"
        android:icon="@drawable/ic_menu_folders_holo_light"
        android:showAsAction="ifRoom|withText"
        android:title="Folders"/>
    <item
        android:id="@+id/menu_refresh"
        android:icon="@drawable/ic_menu_refresh_holo_light"
        android:showAsAction="ifRoom|withText"
        android:title="Refresh"/>
    <item
        android:id="@+id/menu_archive"
        android:icon="@drawable/ic_menu_archive_holo_light"
        android:showAsAction="never"
        android:title="Archive"/>

</menu>

这个就是上面说的在Action item项,这里一共有五个Action Item,大家注意一下几乎每一个Item都有一个Android:showAsAction属性,那么这个属性是如何设置的呢?

这个属性一个有5个值:

android:showAsAction="never"这个表示这个item只能在Action overflow中显示,就是只能点击三个点的图片才能看见

android:showAsAction="ifRoom"设置这个属性时表示item在有限的空间内菜单会显示在Action Item快速的访问栏里,如果空间不够就显示在溢出菜单中,也就是三个点图标里面,这个也是经常使用的

android:showAsAction="always" 这个值表示强制把菜单永远显示在Action Item快速访问栏中,也就是说这个Item 不会隐藏在溢出菜单中,这个值是不提倡的,因为如果Item过多的话每一个iItem都要强制显示在快速访问栏中的话就会导致UI布局混乱的

android:showAsAction="withText" 显示Item的文本,在默认的情况下只是显示Action Item 的图标,如果想让Action Item 显示文本就需要设置这个属性,

android:showAsAction="collapseActionView"这个声明了这个action view应该被折叠到一个按钮中,当用户选择这个按钮时,这个action view展开,至于如何展开之后如何后文有作介绍

注意:在这个xml文件中一定要对每一个item设置android:title属性,如果不设置的话当这个Item出现在溢出菜单时将是空的,因为在溢出菜单中只显示item的title不会显示item的图标,下面两个图中有一个就是不设置title和设置title的区别

 

 

 向上导航

 

如上图,我们在最左边添加一个返回的图标,用户可以通过这个图标进行一些返回的设置,这个相当于一个按钮,添加代码如下:

    private ActionBar actionBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        actionBar=getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

这个actionBar.setDisplayHomeAsUpEnabled就是用于是否显示该返回图标,当用户触摸这个图标时,系统会调用Activity带有android.R.id.home ID的onOptionsItemSelected()方法。在这个响应中,你既可以启动home屏幕,也可以返回你的应用程序结构化层次中用户上一步操作的界面。这个流程的代码:

package com.example.gmailuidemo;

import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.Toast;

public class TestActivity extends Activity{

    private ActionBar actionBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        actionBar=getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub
        switch(item.getItemId()){
        case android.R.id.home:{
            Toast.makeText(this, "android.R.id.home", Toast.LENGTH_LONG).show();
            break;
        }
        }
        return super.onOptionsItemSelected(item);
    }
}

so easy 很容易吧,其实这个相当把这个图标当做action item来使用

注意:这个经常用来作为返回主页的按钮,那么这个时候请记住在Intent对象中请使用FLAG_ACTIVITY_CLEAR_TOP标识,以便你不会这个父Activity存在的情况下,再创建一个新的实例。例如,如果你不使用FLAG_ACTIVITY_CLEAR_TOP标识,那么向上导航后,再按回退按钮,实际上会把用户带到应用程序的下级界面,这是很奇怪的。

 

 添加下拉式导航菜单

 

这个就是下拉式导航菜单,在这个下拉式菜单中有四个选项,我们应该如何实现这个下拉式导航呢?

首先我们先要使用setNavigationMode()方法来启用导航模式,如下代码:

ActionBar actionBar = getActionBar();

actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

 

这个 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);就是表示使用导航模式,设 置导航模式之后就要设置导航菜单项了,设置导航菜单项我们使用的也是BaseAdapter子类,这个很好用吧,如下代码:

 

package com.example.gmailuidemo;

import java.util.List;
import java.util.Map;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter {
    private Context mContext;
    private List<Info> mList;
    
    public MyAdapter(Context context,List<Info> list){
        mContext=context;
        mList=list;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return mList.size();
    }

    @Override
    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return mList.get(arg0);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        LayoutInflater inflater =LayoutInflater.from(mContext);
        convertView =inflater.inflate(R.layout.dropdown_item,null);
        if(convertView!=null){
            TextView titleView=(TextView)convertView.findViewById(R.id.dropdown_title);
            TextView countView=(TextView)convertView.findViewById(R.id.dropdown_count);
            
            titleView.setText(mList.get(position).getTitle());
            countView.setText(mList.get(position).getCount());
        }
        
        return convertView;
    }

}

 

再来看看R.layout.dropdown_item这个布局文件是什么写的

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp"
    android:layout_gravity="center_vertical"    >
    
    <TextView 
        android:gravity="center"
        android:id="@+id/dropdown_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="8dp"
        android:textColor="@android:color/primary_text_light"
        android:text="标题1"
        android:textSize="18sp"
        />
    
     <TextView 
         android:layout_gravity="center"
        android:id="@+id/dropdown_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="4dp"
        android:layout_toRightOf="@id/dropdown_title"
        android:textColor="@android:color/secondary_text_light"
        android:text="23"
        android:textSize="16sp"
       />
</RelativeLayout>

 

那么我们如何把adapter数据设置到ActionBar 中下拉式导航呢,可以使用actionBar.setListNavigationCallbacks(adapter, callback)方法,这个方法有两个参数,第一个就是我们需要的adapter数据,另外一个是callback方法,这个是需要实现 ActionBar.OnNavigationListener回调的一个回调方法,在这个回调中定义当用户选择列表中一个项目时所发生的行为,我们来看 看这个代码如何写

 

    private class MyOnNavigationListener implements OnNavigationListener {  
          
        @Override  
        public boolean onNavigationItemSelected(int itemPosition, long itemId) {  
  
            Toast.makeText(getApplicationContext(),  
                    "当前选择了:" + itemPosition, 0).show();  
  
            return true;  
        }  
        
    }  

 

MyOnNavigationListener 就是实现了OnNavigationListener接口,里面的方法onNavigationItemSelected()就是我们每点击一项时回调给 我们的事件,很简单吧。实现好这个回调接口之后我们就要把数据给添加上去了,看下面的代码:

 

        List<Info> pList=new ArrayList<Info>();
        
        Info info=new Info("标题1","23");
        pList.add(info);
        
        info=new Info("标题2","1");
        pList.add(info);
        
        info=new Info("标题3","54");
        pList.add(info);
        
        info=new Info("标题4","6");
        pList.add(info);
        dataAdapter=new MyAdapter(this, pList);
        
        
        OnNavigationListener callback = new MyOnNavigationListener(); 
        actionBar.setListNavigationCallbacks(dataAdapter, callback);

 

 

添加操作视窗(Action view)

操作视窗是作为操作项目按钮的替代品显示在操作栏中的一个可视构件。例如,如果你有一个用于搜索的可选菜单项,你可以用SearchView类来替代操作栏上的搜索按钮,如下图:

 

这个图是使用google上面的,我们在点击搜索图标的时候就会展现下面的搜索效果,这个效果我们既可以使用android:actionLayout属性或者android:actionViewClass属性来分别指定一个布局资源或要使用的可视构件类,

先来看看android:actionLayout如何使用:

    <item
        android:id="@+id/menu_search"
        android:actionLayout="@layout/collapsibleview"
        android:icon="@drawable/ic_menu_search_holo_light"
        android:showAsAction="collapseActionView|ifRoom"
        android:title="Search"/>

看上面的item 这个showAsAction使用collapseActionView表示这个将会折叠在这个item,android:actionLayout="@layout/collapsibleview"这里就指定了我们的一个layout,来看看我们这个layout是什么写的吧

<?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" >
<EditText 
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:id="@+id/colla_edit"
    />    
<Button 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/colla_btn"
    android:text="搜索"
    />
</LinearLayout>

 

这个就是我们的上面说的那个layout,我们可以到是由一个EditText和Button组成,只要这样配置好之后,在点搜索按钮的时候就会显示出我的这个layout,那么关于这个layout按钮点击事件是如何来处理的呢?来看下面的代码

 

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.gmail, menu);
        
        View view=menu.findItem(R.id.menu_search).getActionView();
        btn=(Button) view.findViewById(R.id.colla_btn);
        btn.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Toast.makeText(GmailActivity.this, "BTNTBTNT", Toast.LENGTH_LONG).show();
            }
        });
        return true;
    }

 

这个就是layout的上面那个button的处理,最关键的一句话就是下面这句:

View view=menu.findItem(R.id.menu_search).getActionView();通过这个就是指定哪个layout,然后在layout中通过findViewById来找到指定的控件。

下面来看android:actionViewClass使用方法,这个我就直接拿google上面的列子了:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@+id/menu_search"

          android:title="@string/menu_search"

          android:icon="@drawable/ic_menu_search"

          android:showAsAction="ifRoom|collapseActionView"

          android:actionViewClass="android.widget.SearchView" />
</menu>

这个android:actionViewClass中指定的View可以是我们自个定义的咯,

 

@Override

public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.options, menu);

    SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();

    // 配置搜索信息并添加事件监听器

    ...

    return super.onCreateOptionsMenu(menu);

}

 

 

使用分离(split)的Action Bar

直接看下面的图片

 

我们发现Action Item在下面了,这样我们可以更好的利用空间进行布局,改成这样也很容易:在AndroidManifest.xml中对于的Activity中添加下面这句就可以了

 

android:uiOptions="splitActionBarWhenNarrow"

 

 

添加Action Provider

与action view(这个就是前面所说的那个搜索框)类似,Action Provider(由ActionProvider类定义的)用一个定制的布局代替一个action item,这个也叫操作提供器要给一个操作项声明一个操作提供器,就要在菜单资源中对应的<item>元素中定义 android:actionProviderClass属性,提供器要使用完整的类名,如下图:

 

 

如 果你想要在action bar中提供一个“共享”操作,以充分利用安装在设备上的其他应用程序(如,把一张图片共享给短短信或社交应用程序使用),那么使用 ShareActionProvider类是一个有效的方法,而不是添加一个调用ACTION_SEND类型Intent对象的action item。当你给一个action item使用ShareActionProvider类时,它会呈现一个带有能够处理ACTION_SEND类型Intent对象的应用程序的下拉列表

创建子菜单的所有逻辑,包括共享目标的封装、点击事件的处理(包在溢出菜单中的项目显示)等,都在ShareActionProvider类中实现了---你需要编写的唯一的代码是给对应的菜单项声明action provider,并指定共享的Intent对象。

默认情况,ShareActionProvider对象会基于用户的使用频率来保留共 享目标的排列顺序。使用频率高的目标应用程序会显示在下来列表的上面,并且最常用的目标会作为默认共享目标直接显示在action bar。默认情况下,排序信息被保存在由DEFAULT_SHARE_HISTORY_FILE_NAME指定名称的私有文件中。如果你只使用一种操作类 型ShareActionProvider类或它的一个子类,那么你应该继续使用这个默认的历史文件,而不需要做任何事情。但是,如果你使用了不同类型的 多个操作的ShareActionProvider类或它的一个子类,那么为了保持它们自己的历史,每种ShareActionProvider类都应该 指定它们自己的历史文件。给每种ShareActionProvider类指定不同的历史文件,就要调用 setShareHistoryFileName()方法,并且提供一个XML文件的名字(如,custom_share_history.xml)注 意:尽管ShareActionProvider类是基于使用频率来排列共享目标的,但是这种行为是可扩展的,并且 ShareActionProvider类的扩展能够基于历史文件执行不同的行为和排序。要添加ShareActionProvider对象,除了需简单 的给android.actionProviderClass属性设定android.widget.ShareActionProvider属性值就可 以了。唯一要做的事情是定义你要用于共享的Intent对象,你必须先调用getActionProvider()方法来获取跟菜单项匹配的 ShareActionProvider对象,然后调用setShareIntent()方法。直接来看代码:

 

    <item
        android:id="@+id/share"
        android:showAsAction="ifRoom"
        android:title="share"
        android:actionProviderClass="android.widget.ShareActionProvider"
        />

 

    @SuppressLint("NewApi") @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.gmail, menu);
        ShareActionProvider mShareActionProvider=(ShareActionProvider) menu.findItem(R.id.share).getActionProvider();
        mShareActionProvider.setShareIntent(getDefaultShareIntent());
        return true;
    }

    private Intent getDefaultShareIntent() {
        // TODO Auto-generated method stub
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.putExtra(Intent.EXTRA_SUBJECT, "test");
        intent.putExtra(Intent.EXTRA_TEXT, "testest");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return intent;
    }

创建自定义的Action Provider

 

当你想要创建一个有动态行为和在溢出菜单中有默认图标的action view时,,继承ActionProvider类来定义这些行为是一个比好的的方案。创建自己的action provider,提供一个有组织的可重用的组件,而不是在Fragment或Activity的代码中处理各种action item的变换和行为。要创建自己的action provider,只需简单的继承ActionProvider类,并且实现合适的回调方法。你应该实现以下重要的回调方法:

 

ActionProvider()

 

这个构造器把应用程序的Context对象传递个操作提供器,你应该把它保存在一个成员变量中,以便其他的回调方法使用。

 

public View onCreateActionView() {

    LayoutInflater layoutInflater = LayoutInflater.from(mContext);

    View view = layoutInflater.inflate(R.layout.action_provider, null);

    ImageButton button = (ImageButton) view.findViewById(R.id.button);

    button.setOnClickListener(new View.OnClickListener() {

        @Override

        public void onClick(View v) {

            // Do something...

        }

    });

    return view;

}

 

OnCreateActionView()

这是你给菜单项定义action view的地方。使用从构造器中接收的Context对象,获取一个LayoutInflater对象的实例,并且用XML资源来填充action view,然后注册事件监听器

onPerformDefaultAction()

在选中溢出菜单中的菜单时,系统会调用这个方法,并且action provider应该这对这个选中的菜单项执行默认的操作。但是,如果你的action provider提供了一个子菜单,即使是溢出菜单中一个菜单项的子菜单,那么也要通过onPrepareSubMenu()回调方法来显示子菜单。这样 onPerformDefaultAction()在子菜单显示时就不会被调用。注意:实现了onOptionsItemSelected()回调方法的 Activity或Frament对象能够通过处理item-selected事件(并且返回true)来覆盖action provider的默认行为,这种情况下,系统不会调用onPerformDefaultAction()回调方法。
上面自定义是google翻译过来的,我直接搬过来用了,哈哈

ActionBar Tab

 

从上图中就是使用ActionBar来设置tab导航模式,要添加一个ActionBar就通过下面几个主要的方法

 

1。设置AcitonBar的操作模式: actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

 

2。添加tab 调用ActionBar的newTab()生成一个ActionBar.tab,还有就是分别使用setText()和setIcon()可以分别设置tab文本和图标,如下代码:

 

        // 生成Tab
        Tab edit = actionBar.newTab().setText("Tab B");
        Tab computer = actionBar.newTab().setText("Tab A");

 

3。定义一个新的类的实现ActionBar.TabListener接口,而且我们要为ActionBar tab添加TabListener,最后再使用addTab把相应的tab添加到ActionBar中,我们来看全部的代码吧

            // 生成Tab  
            Tab edit = actionBar.newTab().setText("Tab B");  
            Tab computer = actionBar.newTab().setText("Tab A");  
            // 为每个Tab添加Listener  
            MyTabListener editListener = new MyTabListener(new AFragment());  
            edit.setTabListener(editListener);  
            MyTabListener computerListener = new MyTabListener(new BFragment());  
            computer.setTabListener(computerListener);  
            // 将Tab加入ActionBar中  
            actionBar.addTab(edit);  
            actionBar.addTab(computer);  
        /**  
         * 实现ActionBar.TabListener接口,构造函数中把fragment传进来了,为了更好的控制fragment  
         */  
        class MyTabListener implements TabListener {  
            // 接收每个Tab对应的Fragment,操作  
            private Fragment fragment;  
      
            public MyTabListener(Fragment fragment) {  
                this.fragment = fragment;  
            }  
      
            @Override  
            public void onTabReselected(Tab tab, FragmentTransaction ft) {  
            }  
      
            @Override  
            // 当Tab被选中的时候添加对应的Fragment  
            public void onTabSelected(Tab tab, FragmentTransaction ft) {  
                ft.replace(R.id.frame_place, fragment, null);   
                // 这里要不然使用  
                                                              
                // ft.replace(R.id.context,fragment, null),之后不能使用commit(),要不然会报错。或者注释这条语句,使用下面注释的语句  
      
                // FragmentTransaction fragmentTransaction =getFragmentManager().beginTransaction();  
                // 试用fragment替换activity中的main组件  
                // fragmentTransaction.replace(R.id.context, fragment);  
                // 提交事物  
                // fragmentTransaction.commit();  
                // <strong>提交事物 </strong>  
            }  
            // 当Tab没被选中的时候删除对应的此Tab对应的Fragment  
            @Override  
            public void onTabUnselected(Tab tab, FragmentTransaction ft) {  
                ft.remove(fragment);  
            }  
      
        }  

 

上下文操作模式

什么是上下文操作模式呢?我们先来看看图片

 

如上图有一个listview,当我们长按是就进入上下文本操作模式如下图:

 

这个就是上下文模式,上下文操作模式是ActionMode类的一个系统实现。使用ActionMode,它会临时占据action bar的位置,但与ActionBar是独立的。所以说上下文操作栏不必跟操作栏关联。它们是独立的操作。对于那些提供上下文操作的View对象,你通常应该在以下两种事件之上调用上下文操作模式:

 

1. 用户在View对象上执行一个长按(long-click)操作。

2. 用户选择了一个复选框或View对象中类似复选框的UI组件。

应用程序如何调用上下文操作模式,并给每个操作定义行为,依赖于你的设计。有以下两种基本的设计

在ListView或GridView对象中的批处理上下文操作

1.  实 现AbsListView.MultiChoiceModeListener接口,并且要用setMultiChoiceModeListener()方 法把它设置给ViewGroup对象。在这个监听器的回调方法中,你能够给这个上下文操作栏指定动作,响应在操作项目上的点击事件,并且处理从 ActionMode.Callback接口中继承来的其他回调方法。


2.  调用带有CHOICE_MODE_MULTIPLE_MODAL参数的setChoiceMode()方法,

先看代码:

先来看看实现AbsListView.MultiChoiceModeListener接口的代码

 

    private class ModeCallback implements ListView.MultiChoiceModeListener {

        //
        
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            Log.d("GmailActivity", "oncreateactionmode");
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.action_mode_menu, menu);
            
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            // TODO Auto-generated method stub
            Log.d("GmailActivity", "ondestroyActionMode");
            
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            Log.d("GmailActivity", "onPrepareActionMode");
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void onItemCheckedStateChanged(ActionMode mode, int position,
                long id, boolean checked) {
            // TODO Auto-generated method stub
            
                mListView.setSelection(position);
                Log.d("sss","position"+position);
            
            
        }
        
    }

 

再看下面代码使用

        mListView=(ListView)findViewById(R.id.mainList);
        String[] list=new String[]{"选项1","选项2","选项3","选项4"};
        mainAdapter=new ArrayAdapter<String>(GmailActivity.this, android.R.layout.simple_list_item_1, list);
        mListView.setAdapter(mainAdapter);
        mCallback=new ModeCallback();
        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        mListView.setMultiChoiceModeListener(mCallback);

针对个别View对象的上下文操作模式

 

1.  实现ActionMode.Callback接口。在它的回调方法中,你能够针对上下文操作栏指定动作,在操作项目上响应点击事件和处理针对这个操作模式的其他生命周期事件。

2.  在显示这个操作栏时,调用startActionMode()方法(如用户长按(long-click)对应的view对象时)

private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
   
    // Called when the action mode is created; startActionMode() was called
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        // Inflate a menu resource providing context menu items
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.context_menu, menu);
        return true;
    }
   
    // Called each time the action mode is shown. Always called after onCreateActionMode, but
    // may be called multiple times if the mode is invalidated.
    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false; // Return false if nothing is done
    }
   
    // Called when the user selects a contextual menu item
    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_share:
                shareCurrentItem();
                mode.finish(); // Action picked, so close the CAB
                return true;
            default:
                return false;
        }
    }
   
    // Called when the user exits the action mode
    @Override
    public void onDestroyActionMode(ActionMode mode) {
        mActionMode = null;
    }
};

我们注意到,这些回调方法处理把ActionMode对象传递给关联的事件之外,几乎完全跟选项菜单的回调方法相同。你能够使用 ActionMode的API对CAB(Context Action Bar)进行各种改变,如用setTitle()和setSubtitle()方法修改标题和子标题(有益于指示有多少项目被选择了)。

我还看到,上例中,当操作模式被销毁时,把mActionMode变量设置为null,接下来,你能看到它是如何被初始化的,以及如何把成员变量保存在你的Activity或Fragment中。

someView.setOnLongClickListener(new View.OnLongClickListener() {
    // Called when the user long-clicks on someView
    public boolean onLongClick(View view) {
        if (mActionMode != null) {
            return false;
        }
   
        // Start the CAB using the ActionMode.Callback defined above
        mActionMode = getActivity().startActionMode(mActionModeCallback);
        view.setSelected(true);
        return true;
    }
});

 

 代码下载:https://files.cnblogs.com/itchq/GmailUIDemo.zip

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2014-06-24 20:45  ip小子  阅读(1260)  评论(0编辑  收藏  举报