• 5) 十分钟学会android--ActionBar知识串烧


    建立ActionBar

    Action bar 最基本的形式,就是为 Activity 显示标题,并且在标题左边显示一个 app icon。即使在这样简单的形式下,action bar对于所有的 activity 来说是十分有用的。它告知用户他们当前所处的位置,并为你的 app 维护了持续的同一标识。

    actionbar-basic

    图 1. 一个有 app icon 和 Activity 标题的 action bar

    设置一个基本的 action bar,需要 app 使用一个 activity 主题,该主题必须是 action bar 可用的。如何声明这样的主题取决于我们 app 支持的 Android 最低版本。本课程根据我们 app 支持的 Android 最低版本分为两部分。

    仅支持 Android 3.0 及以上版本

    从 Android 3.0(API lever 11) 开始,所有使用 Theme.Holo 主题(或者它的子类)的 Activity 都包含了 action bar,当 targetSdkVersion 或 minSdkVersion 属性被设置成 “11” 或更大时,它是默认主题。

    所以,要为 activity 添加 action bar,只需简单地设置属性为 11 或者更大。例如:

    <manifest ... >
        <uses-sdk android:minSdkVersion="11" ... />
        ...
    </manifest>
    

    注意: 如果创建了一个自定义主题,需确保这个主题使用一个 Theme.Holo的主题作为父类。详情见 Action bar 的风格化

    到此,我们的 app 使用了 Theme.Holo 主题,并且所有的 activity 都显示 action bar。

    支持 Android 2.1 及以上版本

    当 app 运行在 Andriod 3.0 以下版本(不低于 Android 2.1)时,如果要添加 action bar,需要加载 Android Support 库。

    开始之前,通过阅读Support Library Setup文档来建立v7 appcompat library(下载完library包之后,按照Adding libraries with resources的指引进行操作)。

    在 Support Library集成到你的 app 工程中之后:

    1、更新 activity,以便于它继承于 ActionBarActivity。例如:

    public class MainActivity extends ActionBarActivity { ... }
    

    2、在 mainfest 文件中,更新 <application> 标签或者单一的 <activity> 标签来使用一个 Theme.AppCompat 主题。例如:

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

    注意: 如果创建一个自定义主题,需确保其使用一个 Theme.AppCompat 主题作为父类。详情见 Action bar 风格化

    现在,当 app 运行在 Android 2.1(API level 7) 或者以上时,activity 将包含 action bar。

    切记,在 manifest 中正确地设置 app 支持的 API level:

    <manifest ... >
        <uses-sdk android:minSdkVersion="7"  android:targetSdkVersion="18" />
        ...
    </manifest>



    添加Action按钮

    Action bar 允许我们为当前环境下最重要的操作添加按钮。那些直接出现在 action bar 中的 icon 和/或文本被称作action buttons(操作按钮)。安排不下的或不足够重要的操作被隐藏在 action overflow (超出空间的action,译者注)中。

    actionbar-actions

    图 1. 一个有search操作按钮和 action overflow 的 action bar,在 action overflow 里能展现额外的操作。

    在 XML 中指定操作

    所有的操作按钮和 action overflow 中其他可用的条目都被定义在 menu资源 的 XML 文件中。通过在项目的 res/menu 目录中新增一个 XML 文件来为 action bar 添加操作。

    为想要添加到 action bar 中的每个条目添加一个 <item> 元素。例如:

    res/menu/main_activity_actions.xml

    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <!-- 搜索, 应该作为动作按钮展示-->
        <item android:id="@+id/action_search"
              android:icon="@drawable/ic_action_search"
              android:title="@string/action_search"
              android:showAsAction="ifRoom" />
        <!-- 设置, 在溢出菜单中展示 -->
        <item android:id="@+id/action_settings"
              android:title="@string/action_settings"
              android:showAsAction="never" />
    </menu>
    

    上述代码声明,当 action bar 有可用空间时,搜索操作将作为一个操作按钮来显示,但设置操作将一直只在 action overflow 中显示。(默认情况下,所有的操作都显示在 action overflow 中,但为每一个操作指明设计意图是很好的做法。)

    icon 属性要求每张图片提供一个 resource ID。在 @drawable/ 之后的名字必须是存储在项目目录 res/drawable/ 下位图图片的文件名。例如:ic_action_search.png 对应 "@drawable/ic_action_search"。同样地,title 属性使用通过 XML 文件定义在项目目录 res/values/ 中的一个 string 资源,详情请参见 创建一个简单的 UI 。

    注意:当创建 icon 和其他 bitmap 图片时,要为不同屏幕密度下的显示效果提供多个优化的版本,这一点很重要。在 支持不同屏幕 课程中将会更详细地讨论。

    如果为了兼容 Android 2.1 的版本使用了 Support 库,在 android 命名空间下 showAsAction 属性是不可用的。Support 库会提供替代它的属性,我们必须声明自己的 XML 命名空间,并且使用该命名空间作为属性前缀。(一个自定义 XML 命名空间需要以我们的 app 名称为基础,但是可以取任何想要的名称,它的作用域仅仅在我们声明的文件之内。)例如:

    res/menu/main_activity_actions.xml

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
        <!-- 搜索, 应该展示为动作按钮 -->
        <item android:id="@+id/action_search"
              android:icon="@drawable/ic_action_search"
              android:title="@string/action_search"
              yourapp:showAsAction="ifRoom"  />
        ...
    </menu>
    

    为 Action Bar 添加操作

    要为 action bar 布局菜单条目,就要在 activity 中实现 onCreateOptionsMenu() 回调方法来 inflate 菜单资源从而获取 Menu 对象。例如:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // 为ActionBar扩展菜单项
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_activity_actions, menu);
        return super.onCreateOptionsMenu(menu);
    }
    

    为操作按钮添加响应事件

    当用户按下某一个操作按钮或者 action overflow 中的其他条目,系统将调用 activity 中onOptionsItemSelected()的回调方法。在该方法的实现里面调用MenuItemgetItemId()来判断哪个条目被按下 - 返回的 ID 会匹配我们声明对应的 <item> 元素中 android:id 属性的值。

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // 处理动作按钮的点击事件
        switch (item.getItemId()) {
            case R.id.action_search:
                openSearch();
                return true;
            case R.id.action_settings:
                openSettings();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    

    为下级 Activity 添加向上按钮

    在不是程序入口的其他所有屏中(activity 不位于主屏时),需要在 action bar 中为用户提供一个导航到逻辑父屏的up button(向上按钮)

    actionbar-up.png

    图 2. Gmail 中的 up button。

    当运行在 Android 4.1(API level 16) 或更高版本,或者使用 Support 库中的 ActionBarActivity 时,实现向上导航需要在 manifest 文件中声明父 activity ,同时在 action bar 中设置向上按钮可用。

    如何在 manifest 中声明一个 activity 的父类,例如:

    <application ... >
        ...
        <!-- 主 main/home 活动 (没有上级活动) -->
        <activity
            android:name="com.example.myfirstapp.MainActivity" ...>
            ...
        </activity>
        <!-- 主活动的一个子活动-->
        <activity
            android:name="com.example.myfirstapp.DisplayMessageActivity"
            android:label="@string/title_activity_display_message"
            android:parentActivityName="com.example.myfirstapp.MainActivity" >
            <!--  meta-data 用于支持 support 4.0 以及以下来指明上级活动 -->
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.myfirstapp.MainActivity" />
        </activity>
    </application>
    

    然后,通过调用setDisplayHomeAsUpEnabled() 来把 app icon 设置成可用的向上按钮:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_displaymessage);
    
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        // 如果你的minSdkVersion属性是11活更高, 应该这么用:
        // getActionBar().setDisplayHomeAsUpEnabled(true);
    }
    

    由于系统已经知道 MainActivity 是 DisplayMessageActivity 的父 activity,当用户按下向上按钮时,系统会导航到恰当的父 activity - 你不需要去处理向上按钮的事件。

    自定义ActionBar的风格

    Action bar 为用户提供一种熟悉可预测的方式来展示操作和导航,但是这并不意味着我们的 app 要看起来和其他 app 一样。如果想将 action bar 的风格设计的合乎我们产品的定位,只需简单地使用 Android 的 样式和主题 资源。

    Android 包括一少部分内置的 activity 主题,这些主题中包含 “dark” 或 “light” 的 action bar 样式。我们也可以扩展这些主题,以便于更好的为 action bar 自定义外观。

    注意:如果我们为 action bar 使用了 Support 库的 API,那我们必须使用(或重写) Theme.AppCompat 家族样式(甚至 Theme.Holo 家族,在 API level 11 或更高版本中可用)。如此一来,声明的每一个样式属性都必须被声明两次:一次使用系统平台的样式属性(android: 属性),另一次使用 Support 库中的样式属性(appcompat.R.attr 属性 - 这些属性的上下文其实就是我们的 app)。更多细节请查看下面的示例。

    使用一个 Android 主题

    Android 包含两个基本的 activity 主题,这两个主题决定了 action bar 的颜色:

    actionbar-theme-dark@2x.png

    actionbar-theme-light-solid@2x.png

    这些主题即可以被应用到 app 全局,也可以通过在 manifest 文件中设置 <application> 元素 或 <activity>元素的 android:theme 属性,对单一的 activity 进行设置。

    例如:

    <application android:theme="@android:style/Theme.Holo.Light" ... />
    

    可以通过声明 activity 的主题为 Theme.Holo.Light.DarkActionBar 来达到如下效果:action bar 为dark,其他部分为light。

    actionbar-theme-light-darkactionbar@2x.png

    当使用 Support 库时,必须使用 Theme.AppCompat 主题替代:

    一定要确保我们使用的 action bar icon 的颜色与 action bar 本身的颜色有差异。Action Bar Icon Pack 为 Holo “dark”和“light”的 action bar 提供了标准的 action icon。

    自定义背景

    为改变 action bar的背景,可以通过为 activity 创建一个自定义主题,并重写 actionBarStyle 属性来实现。actionBarStyle 属性指向另一个样式;在该样式里,通过指定一个 drawable 资源来重写 background 属性。

    actionbar-theme-custom@2x.png

    如果我们的 app 使用了 navigation tabs 或 split action bar ,也可以通过分别设置 backgroundStacked 和 backgroundSplit 属性来为这些条指定背景。

    Note:为自定义主题和样式声明一个合适的父主题,这点很重要。如果没有父样式,action bar将会失去很多默认的样式属性,除非我们自己显式的对他们进行声明。

    仅支持 Android 3.0 和更高

    当仅支持 Android 3.0 和更高版本时,可以通过如下方式定义 action bar 的背景:

    res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- 应用于程序或者活动的主题 -->
        <style name="CustomActionBarTheme"
               parent="@android:style/Theme.Holo.Light.DarkActionBar">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
        </style>
    
        <!-- ActionBar 样式 -->
        <style name="MyActionBar"
               parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
            <item name="android:background">@drawable/actionbar_background</item>
        </style>
    </resources>
    

    然后,将主题应用到 app 全局或单个的 activity 之中:

    <application android:theme="@style/CustomActionBarTheme" ... />
    

    支持 Android 2.1 和更高

    当使用 Support 库时,上面同样的主题必须被替代成如下:

    res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- 应用于程序或者活动的主题 -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.AppCompat.Light.DarkActionBar">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
    
            <!-- 支持库兼容 -->
            <item name="actionBarStyle">@style/MyActionBar</item>
        </style>
    
        <!-- ActionBar 样式 -->
        <style name="MyActionBar"
               parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
            <item name="android:background">@drawable/actionbar_background</item>
    
            <!-- 支持库兼容 -->
            <item name="background">@drawable/actionbar_background</item>
        </style>
    </resources>
    

    然后,将主题应用到 app 全局或单个的 activity 之中:

    <application android:theme="@style/CustomActionBarTheme" ... />
    

    自定义文本颜色

    修改 action bar 中的文本颜色,需要分别设置每个元素的属性:

    • Action bar 的标题:创建一种自定义样式,并指定 textColor 属性;同时,在自定义的 actionBarStyle中为 titleTextStyle 属性指定为刚才的自定义样式。

    注意:被应用到 titleTextStyle 的自定义样式应该使用 TextAppearance.Holo.Widget.ActionBar.Title 作为父样式。

    仅支持 Android 3.0 和更高

    当仅支持 Android 3.0 和更高时,样式 XML 文件应该是这样的:

    res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- 应用于程序或者活动的主题 -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.Holo">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
            <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
            <item name="android:actionMenuTextColor">@color/actionbar_text</item>
        </style>
    
        <!-- ActionBar 样式 -->
        <style name="MyActionBar"
               parent="@style/Widget.Holo.ActionBar">
            <item name="android:titleTextStyle">@style/MyActionBarTitleText</item>
        </style>
    
        <!-- ActionBar 标题文本 -->
        <style name="MyActionBarTitleText"
               parent="@style/TextAppearance.Holo.Widget.ActionBar.Title">
            <item name="android:textColor">@color/actionbar_text</item>
        </style>
    
        <!-- ActionBar Tab标签 文本样式 -->
        <style name="MyActionBarTabText"
               parent="@style/Widget.Holo.ActionBar.TabText">
            <item name="android:textColor">@color/actionbar_text</item>
        </style>
    </resources>
    

    支持 Android 2.1 和更高

    当使用 Support 库时,样式 XML 文件应该是这样的:

    res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- 应用于程序或者活动的主题 -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.AppCompat">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
            <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
            <item name="android:actionMenuTextColor">@color/actionbar_text</item>
    
            <!-- 支持库兼容 -->
            <item name="actionBarStyle">@style/MyActionBar</item>
            <item name="actionBarTabTextStyle">@style/MyActionBarTabText</item>
            <item name="actionMenuTextColor">@color/actionbar_text</item>
        </style>
    
        <!-- ActionBar 样式 -->
        <style name="MyActionBar"
               parent="@style/Widget.AppCompat.ActionBar">
            <item name="android:titleTextStyle">@style/MyActionBarTitleText</item>
    
            <!-- 支持库兼容 -->
            <item name="titleTextStyle">@style/MyActionBarTitleText</item>
        </style>
    
        <!-- ActionBar 标题文本 -->
        <style name="MyActionBarTitleText"
               parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">
            <item name="android:textColor">@color/actionbar_text</item>
            <!-- 文本颜色属性textColor是可以配合支持库向后兼容的 -->
        </style>
    
        <!-- ActionBar Tab标签文本样式 -->
        <style name="MyActionBarTabText"
               parent="@style/Widget.AppCompat.ActionBar.TabText">
            <item name="android:textColor">@color/actionbar_text</item>
            <!-- 文本颜色属性textColor是可以配合支持库向后兼容的 -->
        </style>
    </resources>
    

    自定义 Tab Indicator

    为 activity 创建一个自定义主题,通过重写 actionBarTabStyle 属性来改变 navigation tabs 使用的指示器。actionBarTabStyle 属性指向另一个样式资源;在该样式资源里,通过指定一个state-list drawable 来重写 background 属性。 

    注意:一个state-list drawable 是重要的,它可以通过不同的背景来指出当前选择的 tab 与其他 tab 的区别。更多关于如何创建一个 drawable 资源来处理多个按钮状态,请阅读 State List 文档。

    例如,这是一个状态列表 drawable,为一个 action bar tab 的多种不同状态分别指定背景图片:

    res/drawable/actionbar_tab_indicator.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!-- 按钮没有按下的状态 -->
    
        <!-- 没有焦点的状态 -->
        <item android:state_focused="false" android:state_selected="false"
              android:state_pressed="false"
              android:drawable="@drawable/tab_unselected" />
        <item android:state_focused="false" android:state_selected="true"
              android:state_pressed="false"
              android:drawable="@drawable/tab_selected" />
    
        <!-- 有焦点的状态 (例如D-Pad控制或者鼠标经过) -->
        <item android:state_focused="true" android:state_selected="false"
              android:state_pressed="false"
              android:drawable="@drawable/tab_unselected_focused" />
        <item android:state_focused="true" android:state_selected="true"
              android:state_pressed="false"
              android:drawable="@drawable/tab_selected_focused" />
    
    
    <!--  按钮按下的状态D -->
    
        <!-- 没有焦点的状态 -->
        <item android:state_focused="false" android:state_selected="false"
              android:state_pressed="true"
              android:drawable="@drawable/tab_unselected_pressed" />
        <item android:state_focused="false" android:state_selected="true"
            android:state_pressed="true"
            android:drawable="@drawable/tab_selected_pressed" />
    
        <!--有焦点的状态 (例如D-Pad控制或者鼠标经过)-->
        <item android:state_focused="true" android:state_selected="false"
              android:state_pressed="true"
              android:drawable="@drawable/tab_unselected_pressed" />
        <item android:state_focused="true" android:state_selected="true"
              android:state_pressed="true"
              android:drawable="@drawable/tab_selected_pressed" />
    </selector>
    

    仅支持 Android 3.0 和更高

    当仅支持 Android 3.0 和更高时,样式 XML 文件应该是这样的:

    res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- 应用于程序或活动的主题 -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.Holo">
            <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
        </style>
    
        <!-- ActionBar tabs 标签样式 -->
        <style name="MyActionBarTabs"
               parent="@style/Widget.Holo.ActionBar.TabView">
            <!-- 标签指示器 -->
            <item name="android:background">@drawable/actionbar_tab_indicator</item>
        </style>
    </resources>
    

    支持 Android 2.1 和更高

    当使用 Support 库时,样式 XML 文件应该是这样的:

    res/values/themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- 应用于程序或活动的主题 -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.AppCompat">
            <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item>
    
            <!-- 支持库兼容 -->
            <item name="actionBarTabStyle">@style/MyActionBarTabs</item>
        </style>
    
        <!-- ActionBar tabs 样式 -->
        <style name="MyActionBarTabs"
               parent="@style/Widget.AppCompat.ActionBar.TabView">
            <!-- 标签指示器 -->
            <item name="android:background">@drawable/actionbar_tab_indicator</item>
    
            <!-- 支持库兼容 -->
            <item name="background">@drawable/actionbar_tab_indicator</item>
        </style>
    </resources>

    ActionBar的覆盖叠加

    默认情况下,action bar 显示在 activity 窗口的顶部,会稍微地减少其他布局的有效空间。如果在用户交互过程中要隐藏和显示 action bar,可以通过调用 ActionBar 中的 hide()show()来实现。但是,这将导致 activity 基于新尺寸重新计算与绘制布局。

    为避免在 action bar 隐藏和显示过程中调整布局的大小,可以为 action bar 启用叠加模式(overlay mode)。在叠加模式下,所有可用的空间都会被用来布局就像ActionBar不存在一样,并且 action bar 会叠加在布局之上。这样布局顶部就会有点被遮挡,但当 action bar 隐藏或显示时,系统不再需要调整布局而是无缝过渡。

    Note:如果希望 action bar 下面的布局部分可见,可以创建一个背景部分透明的自定义式样的 action bar,如图 1 所示。关于如何定义 action bar 的背景,请查看 自定义ActionBar的风格

    actionbar-overlay@2x

    图 1. 叠加模式下的 gallery action bar

    启用叠加模式(Overlay Mode)

    要为 action bar 启用叠加模式,需要自定义一个主题,该主题继承于已经存在的 action bar 主题,并设置 android:windowActionBarOverlay 属性的值为 true

    仅支持 Android 3.0 和以上

    如果 minSdkVersion 为 11 或更高,自定义主题必须继承 Theme.Holo 主题(或者其子主题)。例如:

    <resources>
        <!-- 为程序或者活动应用的主题样式 -->
        <style name="CustomActionBarTheme"
               parent="@android:style/Theme.Holo">
            <item name="android:windowActionBarOverlay">true</item>
        </style>
    </resources>
    

    支持 Android 2.1 和更高

    如果为了兼容运行在 Android 3.0 以下版本的设备而使用了 Support 库,自定义主题必须继承 Theme.AppCompat 主题(或者其子主题)。例如:

    <resources>
        <!-- 为程序或者活动应用的主题样式 -->
        <style name="CustomActionBarTheme"
               parent="@android:style/Theme.AppCompat">
            <item name="android:windowActionBarOverlay">true</item>
    
            <!-- 兼容支持库 -->
            <item name="windowActionBarOverlay">true</item>
        </style>
    </resources>
    

    注意,该主题包含两种不同的 windowActionBarOverlay 式样定义:一个带 android: 前缀,另一个不带。带前缀的适用于包含该式样的 Android 系统版本,不带前缀的适用于通过从 Support 库中读取式样的旧版本。

    指定布局的顶部边距

    当 action bar 启用叠加模式时,它可能会遮挡住本应保持可见状态的布局。为了确保这些布局始终位于 action bar 下部,可以使用 actionBarSize 属性来指定顶部margin或padding的高度来到达。例如:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="?android:attr/actionBarSize">
        ...
    </RelativeLayout>
    

    如果在 action bar 中使用 Support 库,需要移除 android: 前缀。例如:

    <!-- 兼容支持库 -->
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="?attr/actionBarSize">
        ...
    </RelativeLayout>
    

    在这种情况下,不带前缀的 ?attr/actionBarSize 适用于包括Android 3.0 和更高的所有版本。

     
  • 相关阅读:
    git 合并两个仓库
    git 合并两个仓库
    操作系统
    域名
    域名
    .NET Framework基本概念
    .NET Framework基本概念
    拓扑排序
    PHP 数组
    PHP Switch 语句
  • 原文地址:https://www.cnblogs.com/chenxd/p/7816939.html
Copyright © 2020-2023  润新知