ActionBar总结

ActionBar是在Android3.0(API11)之后引入的。在API11以下,Android提供了 android.support.v7.app.ActionBar包支持,API11以上,使用android.app.ActionBar使用ActionBar。

一,ActionBar的组成:


1.App Icon   如果当前不是主页,前面可以加个返回箭头
2.View Control   下拉菜单,用于切换下方页面,也可以只是显示标题
3.Action buttons  一般是比较重要的操作按钮放在这个区域

4.Action overflow 其他操作


二,添加/隐藏 ActionBar

使用 support library,给应用添加ActionBar的方法:

1.Activity继承 ActionBarActivity.

2.使用  Theme.AppCompat 开头的主题

<activity android:theme="@style/Theme.AppCompat.Light" ... >

在API11及以上,可以使用 Theme.Holo主题及它的子主题。

如果需要隐藏ActionBar。

API11以下:

ActionBar actionBar = getSupportActionBar();
actionBar.hide();
API11及以上:

在清单文件中去掉:

android:theme="@android:style/Theme.Holo.NoActionBar"
在代码中去掉:

ActionBar actionBar = getActionBar();
actionBar.hide();
代码去掉ActionBar的代码要写在Activity 的onCreate的 setContentView语句前面。

三.App Icon:

ActionBar左侧的图片默认和清单文件的<application>标签下的 android:icon指定的图片一致。如果需要更改,可以在<application>下加上 android:icon,

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        uiOptions="splitActionBarWhenNarrow"
        android:logo="@drawable/cx"
        android:theme="@style/AppTheme" >

四.Action Items:

显示在Action Bar上的Action Button和隐藏在Action overflow中的项都属于Action Item

当Activity启动时,会调用onCreateOptionsMenu()生成action item,每一个action item是在菜单的资源文件中声明的。

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.learnactionbar.MainActivity" >

    <item android:id="@+id/action_search"
          android:icon="@drawable/ic_action_search"
          android:title="搜索"/>
    <item android:id="@+id/action_copy"
          android:icon="@drawable/ic_action_copy"
          android:title="复制"/>
</menu>

在onCreateOptionsMenu中启用这个菜单:

@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

默认的Action Item是放在Action overflow中的,如果需要作为一个Action Button,显示地显示在Action Bar上,则需要在 <item>标签中加上showAsAction="ifRoom"

<item android:id="@+id/action_search"
          android:icon="@drawable/ic_action_search"
          android:showAsAction="ifRoom"
          android:title="搜索"/>


指定了title属性后,当Action Item作为Action Button显示时,长按图标会在图标下面弹出Title。在同时指定了icon和title的情况下,往往只显示icon。

除了ifRoom以外,还可以指定值为always。指定了这个值后,Action Item总是显示为Action Button.

当点击Action Item时,onOptionsItemSelected()被回调,MenuItem作为参数,由于在<item>中指定了id,可以通过item.getItemId()判断哪个被点击。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_search:
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Action Bar的menu文件可以在Fragment的方法中inflate

@Override
		public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
			inflater.inflate(R.menu.main, menu);
		}
同时需要在Fragment的onCreate方法中加上这句:

setHasOptionsMenu(true);
这样一来,当Fragment随Activity启用之后,会先调用Activity的

onCreateOptionsMenu,再调用Fragment的onCreateOptionsMenu,点击Action Item后,会先调用Activity的onOptionsItemSelected,再调用Fragment的onOptionsItemSelected。


五.ActionView:

API3.0以下可以在菜单xml中这样声明ActionView:

<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.example.learnactionbar2.MainActivity" >

    <item
        android:id="@+id/action_tv"
        android:orderInCategory="100"
        android:title="item1"
        android:icon="@drawable/ic_action_search"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionViewClass="android.widget.TextView"
        />

</menu>
app:actionViewClass属性指定了需要在ActionBar上显示的view。collapseActionView属性指定了,ActionView被折叠到Action Button中。

如果需要在代码中对ActionView进行设置,可以在onCreateOptionsMenu中获取它:

@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		MenuItem textItem = menu.findItem(R.id.action_tv);
		TextView tv = (TextView) MenuItemCompat.getActionView(textItem);
		tv.setText("文字");
		return true;
	}
初始界面:

点击放大镜后的效果:


在API11及以上的版本,在xml中,将app:这样的自定义命名空间改为android:,并且在onCreateOptionsMenu中,这样获取:

TextView tv = (TextView) menu.findItem(R.id.action_tv).getActionView();
	显示在		tv.setText("文字");

ActionView显示在ActionBar上面时,点击手机的虚拟返回键或者左边的“up”键都可以收起ActionView。

监听ActionView的显示和折叠,API11以下:

@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		MenuItem textItem = menu.findItem(R.id.action_tv);
		TextView tv = (TextView) MenuItemCompat.getActionView(textItem);
		tv.setText("文字");
		
		MenuItemCompat.setOnActionExpandListener(textItem, new OnActionExpandListener() {

			@Override
			public boolean onMenuItemActionCollapse(MenuItem arg0) {
				Log.v("TEST", "!!onMenuItemActionCollapse!!");
				return true;
			}

			@Override
			public boolean onMenuItemActionExpand(MenuItem arg0) {
				Log.v("TEST", "!!onMenuItemActionExpand!!");
				return true;
			}
			
		});
		
		return true;
	}
API11以上:
		@Override
		public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
			inflater.inflate(R.menu.main, menu);
			
			TextView tv = (TextView) menu.findItem(R.id.action_tv).getActionView();
			tv.setText("文字");
			
			MenuItem m = menu.findItem(R.id.action_tv);
			m.setOnActionExpandListener(new OnActionExpandListener() {

				@Override
				public boolean onMenuItemActionExpand(MenuItem item) {
					Log.v("TEST", "!!onMenuItemActionExpand!!");
					return true;
				}

				@Override
				public boolean onMenuItemActionCollapse(MenuItem item) {
					Log.v("TEST", "!!onMenuItemActionCollapse!!");
					return true;
				}
				
			});
			
		}

六.Action Provider

Action Provider和Action Button的位置一样,当点击它时,可以显示子菜单。

声明 action provider:在menu的<item> 中添加actionProviderClass属性。以分享按钮ShareActionProvider为例:

<item android:id="@+id/action_share"
          android:title="share"
          android:showAsAction="ifRoom"
          android:actionProviderClass="android.widget.ShareActionProvider"
      />
在ActionBar上显示分享按钮后,为其加上分享的方式:

		@Override
		public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
			inflater.inflate(R.menu.main, menu);
			MenuItem shareItem = menu.findItem(R.id.action_share);
			mShareActionProvider = (ShareActionProvider) shareItem.getActionProvider();
			mShareActionProvider.setShareIntent(getDefaultIntent());
		}
		
		private Intent getDefaultIntent() {
		    Intent intent = new Intent(Intent.ACTION_SEND);
		    intent.setType("image/*");
		    return intent;
		}

七.Navigation Tab:

ActionBar上的Tab会根据屏幕大小自适应,在平板这样的宽屏设备上时,Tab会显示在ActionBar上,手机这样的窄屏时,会显示在ActionBar下方。

宽屏:


窄屏:


实现步骤如下:

1.设置NavigationMode为 ActionBar.NAVIGATION_MODE_TABS

2.新建Tab,为Tab添加标题,TabListener

3.为ActionBar添加Tab

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Notice that setContentView() is not used, because we use the root
    // android.R.id.content as the container for each fragment

    // setup action bar for tabs
    ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayShowTitleEnabled(false);

    Tab tab = actionBar.newTab()
                       .setText(R.string.artist)
                       .setTabListener(new TabListener<ArtistFragment>(
                               this, "artist", ArtistFragment.class));
    actionBar.addTab(tab);

    tab = actionBar.newTab()
                   .setText(R.string.album)
                   .setTabListener(new TabListener<AlbumFragment>(
                           this, "album", AlbumFragment.class));
    actionBar.addTab(tab);
}
TabListener代码:

public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    /** Constructor used each time a new tab is created.
      * @param activity  The host Activity, used to instantiate the fragment
      * @param tag  The identifier tag for the fragment
      * @param clz  The fragment's Class, used to instantiate the fragment
      */
    public TabListener(Activity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    /* The following are each of the ActionBar.TabListener callbacks */

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // Check if the fragment is already initialized
        if (mFragment == null) {
            // If not, instantiate and add it to the activity
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            // If it exists, simply attach it in order to show it
            ft.attach(mFragment);
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            // Detach the fragment, because another one is being attached
            ft.detach(mFragment);
        }
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}

TabListener接收Fragment的 Class<T> clz对象作为构造参数,用于在Tab被选中和反选时,通过FragmentTransaction切换。注意这里不需要手动调用FragmentTransaction的commit,系统会自动调用。要获取当前选择的Tab,可以调用 getSelectedNavigationIndex();


八.下拉导航

下拉导航在ActionBar上提供一个Spinner,用于切换视图。

实现下拉导航的步骤:

1.创建一个提供下拉布局内容的SpinnerAdapter

2.实现 ActionBar.OnNavigationListener接口,用户选中下拉列表中item时的行为在这个接口的实现类中定义

3.在Activity的onCreate方法中,设置ActionBar的NavigationMode为NAVIGATION_MODE_LIST

4.通过 setListNavigationCallbacks(),传入adapter和callback参数,设置下拉列表的回调

示例:

public class MainActivity extends Activity {

	String[] mStrings;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
//		setContentView(R.layout.activity_main);
		
		mStrings = getResources().getStringArray(R.array.action_list);


		SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this,
				R.array.action_list,
				android.R.layout.simple_spinner_dropdown_item);
		getActionBar().setDisplayShowTitleEnabled(false);
		getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
		getActionBar().setListNavigationCallbacks(mSpinnerAdapter,
				mOnNavigationListener);

	}

	OnNavigationListener mOnNavigationListener = new OnNavigationListener() {

		@Override
		public boolean onNavigationItemSelected(int position, long itemId) {
			ListContentFragment newFragment = new ListContentFragment();
			FragmentManager fm = getFragmentManager();
			FragmentTransaction ft = fm.beginTransaction();
			ft.replace(android.R.id.content, newFragment, mStrings[position]);
			ft.commit();
			return true;
		}
	};

	public class ListContentFragment extends Fragment {
		private String mText;

		@Override
		public void onAttach(Activity activity) {
			super.onAttach(activity);
			mText = getTag();
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			TextView text = new TextView(getActivity());
			text.setText(mText);
			return text;
		}
	}

}

九.ActionBar的样式

可以在styles.xml中自定义ActionBar的样式。

<resources>

    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <item name="android:actionBarStyle">@style/MyActionBar</item>
    </style>

    <style name="MyActionBar" parent="@style/Widget.AppCompat.ActionBar">
        <item name="android:titleTextStyle">@style/TitleTextStyle</item>
        <item name="android:background">@color/purple</item>
        <!-- Support library -->
        <item name="titleTextStyle">@style/TitleTextStyle</item>
        <item name="background">@color/purple</item>
    </style>

    <style name="TitleTextStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
        <item name="android:textColor">@android:color/holo_green_light</item>
    </style>

</resources>
上面把ActionBar上的Text字体颜色定义成了浅绿色,ActionBar背景色定义成了紫色。


十.ActionMode

有些App实现了这种效果:当对界面上的某个地方长按后,ActionBar上出现一系列的复制/转发等按钮。这种效果是通过ActionMode来实现的。

使用ActionMode的步骤:

1.实现ActionMode.Callback接口

2.为view的长按/点击等事件通过 startActionMode()设置ActionMode

public class MainActivity extends ActionBarActivity {

	private ActionMode mActionMode;
	private TextView tv;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		tv = (TextView) findViewById(R.id.tv);
		tv.setOnClickListener(new OnShowActionMode());
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		if (id == R.id.action_tv) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
	
	private class OnShowActionMode implements OnClickListener {

		@Override
		public void onClick(View v) {
			
			mActionMode = startActionMode(mActionModeCallback);
			mActionMode.setTitle("action mode");
		}
	}
	
	ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
		
		@Override
		public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
			return false;
		}
		
		@Override
		public void onDestroyActionMode(ActionMode mode) {
			
		}
		
		@Override
		public boolean onCreateActionMode(ActionMode mode, Menu menu) {
			MenuInflater inflater = mode.getMenuInflater();
			inflater.inflate(R.menu.menu_action_mode, menu);
			return true;
		}
		
		@Override
		public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
			if (item.getItemId() == R.id.action_copy) {
				Toast.makeText(MainActivity.this, "!!!", Toast.LENGTH_SHORT).show();
			}
			return true;
		}
	};
}
menu_action_mode.xml:

<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.example.learnactionbar2.MainActivity" >

    <item
        android:id="@+id/action_copy"
        android:icon="@drawable/ic_action_copy"
        android:orderInCategory="100"
        android:title="overflow_item"
        app:showAsAction="ifRoom"/>
</menu>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值