ActionBar用途

来源:互联网 发布:云计算产业发展趋势 编辑:程序博客网 时间:2024/04/28 19:40
ActionBar介绍
ActionBar是android窗口应用的一个特征,它主要用于标示应用程序及用户所处的位置并提供相关操作及全局的导航。
ActionBar的主要用途
1 提供一个专门的空间来显示应用的标识并且标识用户所处的位置。
2 为不同的应用程序提供统一的导航模式。ActionBar为Fragment的切换提供了内置的基于tab 的导航。不仅如此它还提供了一个类似DropList的导航供选择使用。
3 将应用中比较重要的动作放置在用户预期的位置上。
你可以在用户需要选择菜单时将应用中的动作放置在ActionBar上。对于比较重要的Action可以放置到ActionBar上常驻,而不太常用的放置到右边overflow menu上。
ActionBar的设计原则
ActionBar是整个应用常驻的一种控件。
If you're new to writing Android apps, note that the action bar is one of the most important design elements you can implement。
ActionBar是开发者需要实现的最重要的设计之一。
ActionBar的组成
ActionBar主要由四个部分组成:AppIcon(应用标识、向主界面导航)、ViewControl(视图切换,或者显示一些描述信息)、ActionButtons(显示应用程序中最重要的动作、长按图标会提示该动作的描述)、ActionOverflow(相对不太常用的动作)

屏幕旋转及不同尺寸的适配
屏幕旋转时我们可以使用SplitBar将动作显示在屏幕的底部

程序动作Action的放置位置
1、MainActionBar
2、TopBar
3、BottomBar                                                                                                         
如果应用允许用户向上导航,那么应该在Appicon上设置向上导航。                        
允许用户快速切换视图,应用应提供全局TAB或者ViewList
如果需要可以使用action overflow 或者 bottom action bar






上下文ActionBar
上下文ActionBar是一个临时的ActionBar,为了某一子任务临时覆盖到普通的ActionBar上面
上下文ActionBar主要用于应用程序需要选择文本或者其他数据的时候。




视图切换的三种模式
tabs, spinners, and drawers.
Tabs分为三种:普通Tab(预想用户会经常切换视图,希望用户知道其他视图)、固定Tab(一般3-4个标签,允许用户在内容上滑动进行切换)、可滑动的Tab(标签数量比较多或者是动态添加的,此时应该允许用户在内容或者标签上进行滑动切换视图)

Spinners:为同一中数据类型集合的页面提供导航

Drawers: slide-out menu,仅仅使用于顶级界面。



Action buttons
ActionBar应该仅仅显示比较重要并且当前界面可用的动作,如果不可用那么直接将其隐藏即可。
其原则为:Frequent、Important、Typical

Action overflow
overflow icon仅仅在用户手机没有菜单键的时候显示,否则当用户单击菜单键的时候就会弹出overflow menu
ActionBar上应该放置几个按钮?
按钮总宽度不能超过ActionBar的总宽度的一半。bottom bar可以完全被使用。

· The screen width in density-independent pixels (dp) determine the number of items that will fit in the main action bar:
o smaller than 360 dp = 2 icons
o 360-499 dp = 3 icons
o 500-599 dp = 4 icons
o 600 dp and larger = 5 icons

In the above table "o" denotes an action bar item and "=" an overflow icon.


开始使用ActionBar
如果应用的主题是Theme.Holo(开发target sdk 11以上默认主题)都可以使用
如果对于某一特定的Activity你不想使用ActionBar那么可以设置该Activity的主题为:Theme.Holo.NoActionBar.
或者在代码中隐藏ActionBar,当你再次希望使用时调用show即可
ActionBar actionBar = getActionBar();
actionBar.hide();
ActionBar的隐藏与重现会导致界面重新layout。如果你的界面需要定期隐藏重现ActionBar那么你可以使用overlay mode模式来避免这种问题,此模式下ActionBar会绘制在ActivityLayout的上层而不是ActionBar原来的位置。使用overlay mode的方式为创建一个样式并设置android:windowActionBarOverlay 为 true.注意在样式中设置 android:windowActionBar 为 false将会导致ActionBar不可用。

添加Action Items
如果菜单中选项有些项是比较常用的,你可以设置它们为Action Items .action item 可以包含一个图标和标题。如下图


如果某一菜单项没有在action item上显示,那么系统将会自动将它们显示在 overflow menu 中
添加Action 方式为 在onCreateOptionsMenu()直接添加菜单项即可:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_activity, menu);
    return true;
}
通过定义菜单项的android:showAsAction来设置其是否为action item
如果需要显示标题,那么可以定义为 android:showAsAction="ifRoom|withText"
此时如果空间允许就会显示标题。
一般来说即使不显示标题我们也应该为每一个菜单项定义标题。这样做主要为了
4 在overflow menu中菜单项仅仅显示标题。
5 有利于读屏软件帮助视障人士。
6 长按只有图标的菜单时会提示标题。
注:如果在Fragment中定义菜单项,在菜单点击事件传递到Fragment中之前会先经过Activity的处理。
当然,你也可以定义showAsAction属性为always让其始终显示,这样做明显是不被建议的。
选择Action Items的原则:
7 Frequently used: It's an action that your users need seven out of ten visits or they use it several times in a row.
Example frequent actions: "New message" in the Messaging app and "Search" on Google Play.
8 Important: It's an action that you need users to easily discover or, if it's not frequently used, it's important that it be effortless to perform in the few cases that users do need it.
Example important actions: "Add network" in Wi-Fi settings and "Switch to camera" in the Gallery app.
9 Typical: It's an action that is typically provided in the action bar in similar apps, so your users expect to find it in yours.
Example typical actions: "Refresh" in an email or social app, and "New contact" in the People app.
一般而言ActionItem不要超过四个,设置、帮助、建议等类似的菜单项最好不要放到 Action Items中。而对于搜索,鉴于有些手机没有搜索键故应作为一个Action Item提供。

使用 split action bar
Android4.0及以上版本提供该功能。
使用该功能的方法是 在Activity或者Application上配置 uiOptions="splitActionBarWhenNarrow"
android系统会依据屏幕参数对ActionBar的样式进行变换,如果屏幕空间比较小,那么navigation tabs有可能自动调整到Main ActionBar中,再者如果你设置了MainActionBar的图标及标题都不可见(setDisplayShowHomeEnabled(false) and setDisplayShowTitleEnabled(false))那么navigation tabs将自动调整到Main ActionBar中。

uiOptions可以被添加到低于4.0的版本中,此时会被自动忽略。

使用 App Icon 进行导航
导航到主界面
添加 setHomeButtonEnabled(true)
只需要监听menuitem为 android.R.id.home的动作即可。一般情况下AppIcon使用的是Activity或者Application的android:icon属性的图标,当使用android:logo属性时,AppIcon会使用logo属性。
如果使用AppIcon导航到主界面Activity时在Intent中添加FLAG_ACTIVITY_CLEAR_TOP属性。为了防止用户从其他应用中进入你的应用并通过Appicon 导航到HomeActivity,你可以添加FLAG_ACTIVITY_NEW_TASK属性, 该属性保证新打开的Activity不会被添加到当前的Task,而是将其添加到你的应用的Task中。如果已经存在这样的Task那么该Task就会被激活,目标的Activity就会收到onNewIntent的消息。因此,如果你的应用程序接受从其他应用启动,那么你可以加入FLAG_ACTIVITY_NEW_TASK标识。
向上导航

向上导航与BACK键导航的区别




向上导航使用:
设置ActionBar的setDisplayHomeAsUpEnabled(true),这样就会显示向上的标识。

监听menuitem为 android.R.id.home的动作即可。
别忘了使用FLAG_ACTIVITY_CLEAR_TOP 标识。

添加 Action View
Action View 是显示在Action Bar上的控件。为了为某菜单项添加Action View可以使用android:actionLayout 或者android:actionViewClass属性直接添加布局或者某个类。
<?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>
showAsAction属性中collapseActionView的意思是该menu Item应收缩显示。当用户选择该菜单项的时候该菜单就会展开。
如果需要对Action View进行适当的预处理可以:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.options, menu);
    SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
    // Configure the search info and add any event listeners
    ...
    return super.onCreateOptionsMenu(menu);
}
处理Action的展开与收缩
ActionView提供了在不切换Activity或者Fragment的情况下进行比较丰富的交互。但是由于空间限制,默认情况下ActionView不应是展开的。
当用户选择相应的menu的时候系统会自动展开对应的ActionView除非你在onOptionsItemSelected()中直接返回true表明你自己已经完全处理了事件。
当用户单击向上导航或者BACK按钮的时候系统会收缩ActionView
如果必要的话你可以在代码中自己控制ActionView的展开与收缩expandActionView() 、collapseActionView() 在 MenuItem.上调用
如果你需要添加搜索的ActionView我们强烈建议你默认情况下收缩显示,并注意监听有搜索键的手机的按键事件(onKeyUp() callback method, listen for the KEYCODE_SEARCH event, then callexpandActionView().)。

当然你也可以对ActionView的展开与收缩事件进行监听。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.options, menu);
    MenuItem menuItem = menu.findItem(R.id.actionItem);
    ...

    menuItem.setOnActionExpandListener(new OnActionExpandListener() {
        @Override
        public boolean onMenuItemActionCollapse(MenuItem item) {
            // Do something when collapsed
            return true;  // Return true to collapse action view
        }

        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
            // Do something when expanded
            return true;  // Return true to expand action view
        }
    });
}
添加 Action Provider
类似于ActionView,ActionProvider 将ActionItem替换成自定义的一个布局。但它同时控制着每一个子控件的行为。当为某一menuitem定义ActionProvider的时候其不仅控制着显示的外观,还控制着当它显示在 overflow menu中时的事件响应。它也可以为ActionBar上或者overflow上的menu提供子菜单。当提供类似的菜单时不用考虑响应菜单事件。

为某一菜单项提供ActionProvider的方法是设置android:actionProviderClass 例如
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_share"
          android:title="@string/share"
          android:showAsAction="ifRoom"
          android:actionProviderClass="android.widget.ShareActionProvider" />
    ...
</menu>
从此刻起,整个ActionItem的行为将由ActionProvider控制(包括显示状态及事件处理)。
当然对于ActionItem的选择事件你也可以在Activity和Fragment的onOptionsItemSelected() 中进行处理,如果你没有处理的话ActionProvider就会收到onPerformDefaultAction()事件。但是如果ActionProvider提供了一个子菜单,那么Activity及Fragment就不会收到onOptionItemSelected事件,因为默认要显示子菜单了。
如果需要加入分享的ActionProvider那么最简洁的办法就是使用ShareActionProvider,此时你只需要在你的MenuItem中声明这个ActionProvider并且声明分享使用的Intent即可。 此时需要调用getActionProvider() 获取 MenuItem 对应的ShareActionProvider , 然后调用 setShareIntent()即可。
如果分享的Intent随着Activity的生命周期是变化的,此时一般可以这么做:
private ShareActionProvider mShareActionProvider;
...

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();

    // If you use more than one ShareActionProvider, each for a different action,
    // use the following line to specify a unique history file for each one.
    // mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");

    // Set the default share intent
    mShareActionProvider.setShareIntent(getDefaultShareIntent());

    return true;
}
// When you need to update the share intent somewhere else in the app, call
// mShareActionProvider.setShareIntent()
自定义ActionProvider
编写ActionProvider的子类,并实现相应的回调函数

onCreateActionView()自定义ActionView
public View onCreateActionView() {
    // Inflate the action view to be shown on the action bar.
    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;
}
onPerformDefaultAction()
当MenuItem被选中的时候会回调该函数,如果你定义了onPrepareSubMenu() 来提供了一个子菜单,那么该函数就不会被调用。
如果Activity和Fragment实现onOptionsItemSelected() 处理该事件那么该函数也不会被调用。

添加 Navigation Tabs
ActionBar的Tabs会被系统自动调整,如果ActionBar的空间足够大就放到ActionBar上,否则就放到下面。
为了实现使用Tab进行Fragment的切换,我们需要在Tab的选择事件中进行Fragment的切换。此时你需要定义一个ViewGroup来定义一个Fragment与Tab相联系,
当你已经设计好在什么地方展现Fragments的时候,添加Tab的做法如下:
10 实现ActionBar.TabListener来实现用户Tab切换的监听以实现相应的Fragment的切换。
11 实例化ActionBar.Tab 并设置监听ActionBar.TabListener 通过调用 setTabListener()并通过setText() 和 setIcon()设置Tab的图标和标题.
12 将Tab添加到ActionBar使用addTab().
以下为简单例子

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.
    }
}


注意:对于这里面的TransAction你不能调用commit,系统会帮你调用,也不能添加到BackStake
不仅如此,我们还需要调用setNavigationMode(NAVIGATION_MODE_TABS)使得Tab可见,另外我们还可以设置setDisplayShowTitleEnabled(false)使得Title被隐藏。

例子
@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 = getActionBar();
    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);
}

添加下拉列表选择
使用下拉列表的方法
13 提供一个SpinnerAdapter来标识所要显示的列表
14 实现ActionBar.OnNavigationListener 来监听用户选择
15 在onCreate中设置导航模式 setNavigationMode()
16 使用setListNavigationCallbacks()设置数据和监听事件
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);

为ActionBar添加样式
所有的9-patch图像应该高度小于40dp宽度小于30dp放置到mdpi文件夹中

android:windowActionBarOverlay设置Actionbar是否应该浮于Activity上。此时需要注意被ActionBar覆盖的视图部分,我们可以在xml文件中引用ActionBar的高度:
<SomeView
    ...
    android:layout_marginTop="?android:attr/actionBarSize" />
当然也可以通过getHeight()来获得ActionBar的高度。
ActionItem的一些样式

android:actionButtonStyle
按钮的样式
android:actionBarItemBackground
每一个ActionItem的背景
android:itemBackground
每一个 overflow menu 的背景
android:actionBarDivider
actionItem 的分隔符
android:actionMenuTextColor
文字颜色
android:actionMenuTextAppearance
字体类型
android:actionBarWidgetTheme
Defines a theme resource for widgets that are inflated into the action bar as action views. (Added in API level 14.)

导航Tab的样式
android:actionBarTabStyle
tab的样式
android:actionBarTabBarStyle
导航栏下面短条的样式
android:actionBarTabTextStyle
字体样式

下拉视图样式
android:actionDropDownStyle
下拉导航栏的样式

自定义样式的时候使用父样式是不错的选择。

深度自定义
如果你需要更高级别的自定义你可以在Activity的Them中添加android:actionBarStyle and android:actionBarSplitStyle 等样式。每一个都可以引用其他自己定义的样式,这样你就可以为所欲为了,例如ActionBar的背景: android:background, android:backgroundSplit, 和 android:backgroundStacked.如果你需要自定义这些属性,别忘了使用系统样式作为父样式
例:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- the theme applied to the application or activity -->
    <style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
        <item name="android:actionBarStyle">@style/MyActionBar</item>
        <!-- other activity and action bar styles here -->
    </style>

    <!-- style for the action bar backgrounds -->
    <style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar">
        <item name="android:background">@drawable/ab_background</item>
        <item name="android:backgroundStacked">@drawable/ab_background</item>
        <item name="android:backgroundSplit">@drawable/ab_split_background</item>
    </style>
</resources>

转自:http://www.apkbus.com/android-122534-1-1.html

原创粉丝点击