Android ActionBar使用
Posted dsliang12
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android ActionBar使用相关的知识,希望对你有一定的参考价值。
转载请标明出处:
http://blog.csdn.net/zq2114522/article/details/50576158;
本文出自:【梁大盛的博客】
android ActionBar使用
很久之前看Google官方一个Note笔记本代码.那时候觉得很神奇程序上面那一栏东西会随着Activity的跳转进行切换按钮,并且当长按那些按钮的时候会有提示按钮的功能.那时候还没意识到那就是ActionBar.当然那时候只是一个菜鸟那时候也没怎么了解过ActionBar,就是觉得很神奇.很诧异到底是什么实现的.最后时间长了很没深究.这几天有空档把ActionBar英文文档彻头彻尾的看了一遍.突然想起以前不理解的东西原来就是ActionBar.在后面的版本因为ActionBar自身的原因引入ToolBar那也是后话了,但是必须知道ToolBar也是基于ActionBar很多功能来实现的.
ActionBar在Android 3.0(Api 11)引入的一个概念.那就意味着Android 3.0以前的FrameWork没有ActionBar存在的.Android 3.0推出的时候,也推出support library借此支持旧版本的机器(Android 2.1-Api 7及其以上的版本)能用上ActionBar等新东西.
添加ActionBar
Android 3.0为分界线.如果只运行在Android 3.0以后的机器可以直接使用ActionBar无需导入其他support library.但是为了更好的兼容性,一般都推荐使用support library借此能支持Android 2.1以上的机器.
如果你的程序只允许在Android 3.0及其以上的机器(minSdkVersion 11)
使用的包:
import android.app.ActionBarActivity只需继承android.app.Activity
“application”或者”activity”的android:theme属性必须是Theme.Holo(或者是Theme.Holo的子类)
如果你的程序支持在Android 2.1及其以上的机器(minSdkVersion 7)
使用的包:
import android.support.v7.app.ActionBarActivity必须继承android.support.v7.app.AppCompatActivity或者android.support.v7.app.ActionBarActivity(AppCompatActivity和ActionBarActivity的区别.早期通过继承ActionBarActivity实现低版本支持ActionBar.在Support Library更新到v22.1的时候引入AppCompatActivity代替ActionBarActivity.在以后版本我们使用ActionBarActivity即可.)
“application”或者”activity”的android:theme属性必须是Theme.AppCompat(或者是Theme.AppCompat的子类)
添加ActionBar需要关注的地方就是这三点.
简单代码(使用support library,以便支持到更低的版本)
MainActivity.java
package com.example.dsliang.actionbardemo;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
public class MainActivity extends ActionBarActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dsliang.actionbardemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ActionBar!" />
</LinearLayout>
build.gradle
apply plugin: 'com.android.application'
android
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig
applicationId "com.example.dsliang.actionbardemo"
minSdkVersion 7
targetSdkVersion 23
versionCode 1
versionName "1.0"
buildTypes
release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
dependencies
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
运行在Android 4.1.1是成长着样子的
运行在Android 2.3.7是成长着样子的
隐藏、显示ActionBar
获取ActionBar实例
如果使用FrameWork的Actionbar在onCreate函数通过getActionBar函数获取ActionBar的实例.(如果使用support library库需要使用getSupportActionBar函数获取ActionBar的实例)
注意:如果当你使用support library库的时候使用getActionBar函数获取ActionBar的实例.返回的值是null.反之也是同理.(getActionBar函数 - minSdkVersion 11)
- 隐藏Actionbar
ActionBar.hide()函数 显示ActionBar
ActionBar.show()函数注意:默认每次显示/隐藏ActionBar都会导致布局重新加载.视觉效果上会导致隐藏的时候整个布局给拉伸一次,显示又会导致压缩一次.针对需要频繁隐藏/显示ActionBar的情况可以将ActionBar设置成Overlay模式(覆盖在layout层上,像FrameLayout的效果.即使隐藏/显示也不会导致布局重新加载).
隐藏/显示效果:
隐藏/显示明显看到布局有重新加载.
ActionBar OverLyaout模式
(只是修改了AndroidManifest.xml和styles.xml)
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dsliang.actionbardemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="windowActionBarOverlay">true</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
效果:
Action Button
在Android 3.0以后一个很值得注意到地方,他取消了菜单键并且将菜单功能集成到ActionBar里面了.由此Action Button诞生.Action Button是将本来的六宫格菜单都搬到ActionBar的右侧.在能显示的前提下都将菜单已标题或者图标加标题的形式显示在ActionBar的右侧.但是众所周知,ActionBar控件也不是很大.ActionBar会将无法容纳的Action Button放置在Overflow按钮里面(三个小点的图标).
很久之前的菜单键是这样的(Android 2.3.7)
现在是这样的(Android 4.1.1)
定义菜单键(Action Button)
定义菜单键的xml文件(一般放置在res/menu/目录下)
根节点”menu”并且包含子节点”item”,在子节点”item”定义菜单键的属性.包括:title-标题,icon-图标,id-id号,showAsAction-按钮的表现形式,等等.
注意:在Android 3.0以前的版本,FrameWork里面并没有showAsAction这个属性.使用这属性的使用要定义命名空间.
调用onCreateOptionMenu函数加载Action Button
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_search"
app:showAsAction="always"
android:icon="@android:drawable/ic_menu_search"
android:title="search" />
<item
android:id="@+id/menu_camera"
android:icon="@android:drawable/ic_menu_camera"
app:showAsAction="ifRoom|withText"
android:title="camera" />
<item
android:id="@+id/menu_add"
android:icon="@android:drawable/ic_menu_add"
app:showAsAction="ifRoom"
android:title="add" />
<item
android:id="@+id/menu_delete"
android:icon="@android:drawable/ic_menu_delete"
app:showAsAction="never"
android:title="delete" />
</menu>
Activity类实现onCreateOptionsMenu方法即可
@Override
public boolean onCreateOptionsMenu(Menu menu)
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
showAsAction属性解析
always:显示在ActionBar,但是只有有空间才会显示,没空间的情况下会放置在OverFlow里面
ifRoom:如果有足够空间则显示在ActionBar,没空间的情况下会放置在OverFlow里面
never:安置在OverFlow里面
withText:如果有足够空间把标题也显示在图标右侧并且用”|”号分割将图标和标题分割开.(Action Button Icon属性是可选的.如果显示在ActionBar,那么只会显示图标.添加withText以后如果显示在ActionBar的时候有足够空间会把标题和图标以前显示.当显示在ActionBar并且没显示标题的时候,长按图标会弹出标题.当Action Button显示在OverFlow的时候只会显示标题不会显示图标.)
效果图:
响应Action Button点击事件
继承Activity的onOptionsItemSelected函数,当点击Action Button的时候会调用onOptionsItemSelected函数通过MenuItem.getId可以获取到哪一个Action Button给点击.
注意:onOptionsItemSelected函数的返回值.如果返回真那就意味着已经把这一个事件消耗了.如果返回假这事件会继续传递下去(传递到Fragment).
注意:不仅仅可以通过继承Activity的onOptionsItemSelected函数添加Action Button.还可以通过继承Fragment的onOptionsItemSelected函数实现添加Action Button.区别在于通过Fragment添加的Action Button项会排列在通过Activity添加的Action Button后面.当用户点击Action Button的时候会调用activity的onOptionsItemSelected函数.如果activity的onOptionsItemSelected返回true表明此事件已经处理了不在传递.如果activity的onOptionsItemSelected返回false那么会继续调用Fragment的onOptionsItemSelected函数继续处理这次点击事件.
public class MainActivity extends AppCompatActivity
...
public boolean onOptionsItemSelected(MenuItem item)
switch (item.getItemId())
case R.id.menu_add:
//Do something
return true;
case R.id.menu_camera:
//Do something
return true;
case R.id.menu_delete:
//Do something
return true;
case R.id.menu_search:
//Do something
return true;
return super.onOptionsItemSelected(item);
4.1.1 Overflow效果
2.37 Overflow效果
注意:Overflow运行效果区别原因.如果有menu按钮那么不会再显示Overflow按钮
导航栏
ActionBar除了集成了Action Button之外还暗藏一个导航栏.
在使用ActionBar的Tab功能之前,你的布局需要预留一个地方给Tab所需显示的控件.一般做法是使用FrameLayout显示Tab需要显示的内容.切换Tab的时候将Tab对于的Fragment放置到该容器当中.
使用方法:
调用getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS),此函数的功能是把Tab栏显示出来.
实现ActionBar.TabListener接口
onTabSelected - Tab给选择的时候调用
onTabUnselected - Tab反选择的时候调用
onTabReselected - Tab选中状态再给选择的时候调用(一般不做处理)实现ActionBar.Tab,ActionBar.Tab代表一个Tab选项
调用ActionBar.addTab函数把Tab添加到ActionBar
代码:
MainActivity.java
package com.example.dsliang.actionbardemo;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity
ActionBar mActionBarSupport;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar.Tab tab;
mActionBarSupport = getSupportActionBar();
mActionBarSupport.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
tab = mActionBarSupport.newTab()
.setText(R.string.tab_sports)
.setTabListener(new TabListener<TabSportFragment>(this, "体育新闻", TabSportFragment.class));
mActionBarSupport.addTab(tab);
tab = mActionBarSupport.newTab()
.setText(R.string.tab_international)
.setTabListener(new TabListener<TabInternationalFragment>(this, "国际新闻", TabInternationalFragment.class));
mActionBarSupport.addTab(tab);
tab = mActionBarSupport.newTab()
.setText(R.string.tab_focus)
.setTabListener(new TabListener<TabFocusFragment>(this, "今日焦点", TabFocusFragment.class));
mActionBarSupport.addTab(tab);
class TabListener<T extends Fragment> implements ActionBar.TabListener
private Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
public TabListener(Activity activity, String tag, Class<T> clz)
mActivity = activity;
mTag = tag;
mClass = clz;
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft)
if (mFragment == null)
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(R.id.fragment_content, mFragment, mTag);
else
ft.attach(mFragment);
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft)
if (mFragment != null)
ft.detach(mFragment);
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft)
TabFocusFragment.java
package com.example.dsliang.actionbardemo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by dsliang on 2016/1/25.
*/
public class TabFocusFragment extends Fragment
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View view;
TextView textView;
view = inflater.inflate(R.layout.tab_fragment_layout, container, false);
textView = (TextView) view.findViewById(R.id.txtTextView);
textView.setText(R.string.tab_focus);
return view;
TabInternationalFragment.java
package com.example.dsliang.actionbardemo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by dsliang on 2016/1/25.
*/
public class TabInternationalFragment extends Fragment
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View view;
TextView textView;
view = inflater.inflate(R.layout.tab_fragment_layout, container, false);
textView = (TextView) view.findViewById(R.id.txtTextView);
textView.setText(R.string.tab_international);
return view;
TabSportFragment.java
package com.example.dsliang.actionbardemo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by dsliang on 2016/1/25.
*/
public class TabSportFragment extends Fragment
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View view;
TextView textView;
view = inflater.inflate(R.layout.tab_fragment_layout, container, false);
textView = (TextView) view.findViewById(R.id.txtTextView);
textView.setText(R.string.tab_sports);
return view;
activity_main.xml
<?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:gravity="center"
android:orientation="vertical">
<FrameLayout
android:id="@+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</LinearLayout>
tab_fragment_layout.xml
<?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:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/txtTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp" />
</LinearLayout>
strings.xml
<resources>
<string name="app_name">ActionBarDemo</string>
<string name="tab_sports">体育新闻</string>
<string name="tab_international">国际新闻</string>
<string name="tab_focus">今日焦点</string>
</resources>
TabFocusFragment、TabInternationalFragment、TabSportFragment三个Fragment代码是基本一样的。实质应该用不同的Fragment代替,仅作示范。
具体代码里面已经很清楚了,就不再细说了。(除了导航栏意外还有另一种下拉导航栏,基本都是大同小异的。)
效果:
Action View
除了Action Button和Tab之外还有Action View。
什么是Action View?
我们可以在ActionBar中嵌入我们自定义的Layout或者View控件,称之Action View。
有什么用途?
在不改变ActionBar、Fragment和Activity的前提下快速完成某些操作,如:搜索等(当然在ActionBar内嵌一个SearchView是最常见的)。
使用方法:
和定义Action Buton基本一样,就是多了一个actionViewClass属性(collapseActionView表明将ActionView折叠成一个ActionButton)
例如:app:showAsAction=”ifRoom|collapseActionView”
注意:actionViewClass属性也是在低版本没定义的。需要在xml文件新建命名空间
查找Actoin View对应的View
代码
getMenuInflater().inflate(R.menu.main_activity_actions, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
注意:MenuItemCompat.getActionView(searchItem)是Api 7提供的函数。Api 11以后可以使用menu.findItem(R.id.action_search).getActionView()
- 定义Action View回调事件
通过MenuItemCompat.setOnActionExpandListener设置折叠/打开监听函数
(具体可以看后面提供的代码)
代码
MainActivity.java
package com.example.dsliang.actionbardemo;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity
ActionBar mActionBarSupport;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar.Tab tab;
mActionBarSupport = getSupportActionBar();
@Override
public boolean onCreateOptionsMenu(Menu menu)
MenuItem menuItem;
SearchView searchView;
getMenuInflater().inflate(R.menu.menu, menu);
menuItem = menu.findItem(R.id.menu_search);
searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
//可以针对searchView设置相应的监听函数
//....searchView
//设置折叠监听函数
MenuItemCompat.setOnActionExpandListener(menuItem, new MenuItemCompat.OnActionExpandListener()
@Override
public boolean onMenuItemActionExpand(MenuItem item)
Toast.makeText(MainActivity.this, "ActionView open", Toast.LENGTH_SHORT).show();
return true;
@Override
public boolean onMenuItemActionCollapse(MenuItem item)
Toast.makeText(MainActivity.this, "ActionView collapse", Toast.LENGTH_SHORT).show();
return true;
);
return super.onCreateOptionsMenu(menu);
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_search"
app:showAsAction="ifRoom|collapseActionView"
android:icon="@android:drawable/ic_menu_search"
android:title="search"
app:actionViewClass="android.support.v7.widget.SearchView"/>
<item
android:id="@+id/menu_camera"
android:icon="@android:drawable/ic_menu_camera"
app:showAsAction="ifRoom"
android:title="camera" />
<item
android:id="@+id/menu_add"
android:icon="@android:drawable/ic_menu_add"
app:showAsAction="ifRoom"
android:title="add" />
<item
android:id="@+id/menu_delete"
android:icon="@android:drawable/ic_menu_delete"
app:showAsAction="ifRoom"
android:title="delete" />
</menu>
效果:
Action View 效果
总结:这一篇写的挺多的.遗憾AcionBar Home按钮没写.打算等有时间继续写下去.此外下一篇写Menu的使用.因为ActionBar使用必定就牵涉到Menu了!
参考
1:ActionBar http://android.xsoftlab.net/guide/topics/ui/actionbar.html
2:ActionBar http://android.xsoftlab.net/reference/android/support/v7/app/ActionBar.html
3:Menu http://android.xsoftlab.net/reference/android/view/Menu.html
4:如何在有菜单键的机器显示OverFlow按钮 http://www.jb51.net/article/52468.htm
5:Android ActionBar完全解析,使用官方推荐的最佳导航栏 http://itindex.net/detail/49902-android-actionbar-%E5%AE%8C%E5%85%A8
6:ActionBar侧拉栏 http://blog.csdn.net/jjwwmlp456/article/details/41206513
以上是关于Android ActionBar使用的主要内容,如果未能解决你的问题,请参考以下文章
如何使用android-support-V7包中ActionBar