zoukankan      html  css  js  c++  java
  • <Android 基础(六)> ActionBar

    介绍

    Action Bar是一种新増的导航栏功能,在Android 3.0之后加入到系统的API当中,它标识了用户当前操作界面的位置,并提供了额外的用户动作、界面导航等功能。使用ActionBar的好处是,它可以给提供一种全局统一的UI界面,使得用户在使用任何一款软件时都懂得该如何操作,并且ActionBar还可以自动适应各种不同大小的屏幕。下面是一张使用ActionBar的界面截图:
    这里写图片描述

    其中,[1]是ActionBar的图标,[2]是两个action按钮,[3]是overflow按钮。

    基本使用

    添加ActionBar


    –布局文件–
    AndroidStudio自动创建的MainActivity继承自AppCompatActivity本身携带有ActionBar,这里想要使用ToolBar来实现ActionBar的功能,需要先修改下theme

        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>

    使用Theme.AppCompat.Light.NoActionBar作为activity的风格,这里插述一下相关属性代表的界面位置

    这里写图片描述

    创建ToolBar对应的xml文件
    toolbar.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.Toolbar android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
    </android.support.v7.widget.Toolbar>

    这里把这个文件单独作为一个xml方便多个layout中包含

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rootlayout"
        tools:context="mraz.com.actionbardemo.MainActivity"
        android:orientation="vertical">
    
        <include layout="@layout/toolbar"/>
        <TextView
            android:id="@+id/tv_hello"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!" />
    </LinearLayout>

    主界面对应的layout中include刚才创建的toolbar.xml文件

    main_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/action_search"
            android:icon="@drawable/ic_search_black_24dp"
            app:actionViewClass="android.support.v7.widget.SearchView"
            android:title="Search"
            android:inputType="textCapWords"
            android:imeOptions="actionSearch"
            android:orderInCategory="80"
            app:showAsAction="ifRoom|collapseActionView"/>
    
        <item android:id="@+id/action_settings"
            android:icon="@drawable/ic_apps_black_24dp"
            android:title="Settings"
            android:orderInCategory="100"
            app:showAsAction="always"/>
    
        <item android:id="@+id/action_info"
            android:title="Details"
            android:icon="@drawable/ic_report_black_24dp"
            android:orderInCategory="90"
            app:showAsAction="ifRoom"/>
    
    </menu>

    menu 对应的属性解释一下

    属性值 意义
    id 控件id
    title 标题(必需)
    icon 图标
    showAsAction 控制显示到actionbar还是overflow
    actionViewClass 构建视图所使用的View
    actionProviderClass 基本同上
    menuCategory 同种菜单项的种类。该属性可取4个值:container、system、secondary和alternative。通过menuCategroy属性可以控制菜单项的位置。例如将属性设为system,表示该菜单项是系统菜单,应放在其他种类菜单项的后面。
    orderInCategory 同种类菜单的排列顺序。该属性需要设置一个整数值,越小越靠左

    showAsAction的几个属性,解释一下

    属性 意义
    ifRoom 根据当前的空间大小调整
    never 永远不会显示。只会在溢出列表中显示,而且只显示标题,所以在定义item的时候,最好把标题都带上
    always 无论是否溢出,都会显示
    withText withText值示意Action bar要显示文本标题。Action bar会尽可能的显示这个标题,但是,如果图标有效并且受到Action bar空间的限制,文本标题有可能显示不全。
    collapseActionView 声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。否则,这个操作视窗在默认的情况下是可见的,并且即便在用于不适用的时候,也要占据操作栏的有效空间。一般要配合ifRoom一起使用才会有效果。

    –代码使用–

    package mraz.com.actionbardemo;
    
    import android.os.Bundle;
    import android.support.design.widget.Snackbar;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.LinearLayout;
    
    public class MainActivity extends AppCompatActivity {
    
        LinearLayout rootlayout;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            rootlayout = (LinearLayout) findViewById(R.id.rootlayout);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
            toolbar.setNavigationIcon(R.drawable.ic_menu_black_24dp);
    
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.main_menu, menu);
            return true;
        }
    
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.action_info:
                    Snackbar.make(rootlayout, " Info ", Snackbar.LENGTH_SHORT).show();
                    break;
                case R.id.action_search:
                    Snackbar.make(rootlayout, " Search ", Snackbar.LENGTH_SHORT).show();
                    break;
                case R.id.action_settings:
                    Snackbar.make(rootlayout, " Settings ", Snackbar.LENGTH_SHORT).show();
                    break;
            }
            return super.onOptionsItemSelected(item);
        }
    }

    比较关键的只有3行代码

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); //获取toolbar
    setSupportActionBar(toolbar); //设置成ActionBar
    getMenuInflater().inflate(R.menu.main_menu, menu); //创建actionbar的菜单项

    有了这些代码基本上就可以显示ActionBar,当然要实现与用户的交互,就需要对每一个item做对应的响应处理,这里根据菜单的id,做了简单的Snackbar的展示,开发者可以根据自己的需要实现更复杂的逻辑

        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.action_info:
                    Snackbar.make(rootlayout, " Info ", Snackbar.LENGTH_SHORT).show();
                    break;
                    ……
        }

    –效果图–
    这里写图片描述


    使用Action View

    上面的例子中有个比较特殊的Menu Item

        <item android:id="@+id/action_search"
            android:icon="@drawable/ic_search_black_24dp"
            app:actionViewClass="android.support.v7.widget.SearchView"
            android:title="Search"
            android:inputType="textCapWords"
            android:imeOptions="actionSearch"
            android:orderInCategory="80"
            app:showAsAction="ifRoom|collapseActionView"/>

    这里使用了actionViewClass,这个要设置shwoAsAction为 ifRoom|collapseActionView使用才行,其实删除collapseActionView,也是可以正常使用,只是体现的方式不一样。获取SearchView的方式

    MenuItem item = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) item.getActionView();

    SerachView 对象拿到之后可以对其属性进行操作。给Action View添加展开和收起的事件监听,实现方式

        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.main_menu, menu);
            MenuItem searchitem = menu.findItem(R.id.action_search);
            SearchView searchView = (SearchView) searchitem.getActionView();
            MenuItemCompat.setOnActionExpandListener(searchitem, new MenuItemCompat.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    Snackbar.make(rootlayout, " onMenuItemActionExpand ", Snackbar.LENGTH_SHORT).show();
                    return true;
                }
    
                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    Snackbar.make(rootlayout, " onMenuItemActionCollapse ", Snackbar.LENGTH_SHORT).show();
                    return true;
                }
            });
            return true;
        }

    拿到searchItem之后,执行
    MenuItemCompat.setOnActionExpandListener(searchitem, new MenuItemCompat.OnActionExpandListener() );

    –效果图–
    这里写图片描述


    使用ActionProviderClass

    menu文件中使用

    <item android:title="Share"
        android:actionProviderClass="android.widget.ShareActionProvider"
        android:orderInCategory="100"
        app:showAsAction="always"
        />

    类似的方式获取ActionProvider

    MenuItem shareItem = menu.findItem(R.id.action_share);
    ShareActionProvider mShareActionProvider = (ShareActionProvider)
                    MenuItemCompat.getActionProvider(shareItem);
    mShareActionProvider.setShareIntent(……);

    针对ActionProvider可以实现自定义的ActionProvider,继承基础类ActionProvider


    ActionBar导航

    启用ActionBar图标导航的功能,可以允许用户根据当前应用的位置来在不同界面之间切换。比如,A界面展示了一个列表,点击某一项之后进入了B界面,这时B界面就应该启用ActionBar图标导航功能,这样就可以回到A界面。
    我们可以通过调用setDisplayHomeAsUpEnabled()方法来启用ActionBar图标导航功能

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    此时ActionBar左侧会出现一个返回的按钮
    这里写图片描述

    针对这返回按钮的事件响应还是在public boolean onOptionsItemSelected(MenuItem item) 方法中实现,它有一个固定的资源Id—- android.R.id.home

    case android.R.id.home:
         finish();
         break;

    简单的执行下和返回键相同的操作。结束当前activity

    实现Activity之间的快速切换
    新建一个ParentActivity.java

    package mraz.com.actionbardemo;
    
    import android.content.Context;
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.TextView;
    
    public class ParentActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_parent);
    
            final Context mContext = this;
            TextView textView = (TextView) findViewById(R.id.tv_parent);
            textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setClass(mContext , MainActivity.class);
                    startActivity(intent);
                }
            });
        }
    }

    AndroidManifest.xml文件中做如下修改

    
        <application
            ……>
            <activity android:name=".ParentActivity">
    
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <activity android:name=".MainActivity"
                android:parentActivityName="mraz.com.actionbardemo.ParentActivity">
            </activity>
    
        </application>

    这一句很关键
    android:parentActivityName=”mraz.com.actionbardemo.ParentActivity”>
    设置父Activity的名称,ParentActivity为启动Activity同时是MainActivity的父Activity
    然后在MainActivity中针对这个返回按钮做一下处理,不再是简单的结束掉当前的这个Activity了,需要做出对应的导航的处理逻辑

     case android.R.id.home:
         Intent upIntent = NavUtils.getParentActivityIntent(this);
         if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
             TaskStackBuilder.create(this)
                             .addNextIntentWithParentStack(upIntent)
                             .startActivities();
             } else {
                 upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                 NavUtils.navigateUpTo(this, upIntent);
             }
         break;

    其中,调用NavUtils.getParentActivityIntent()方法可以获取到跳转至父Activity的Intent,然后如果父Activity和当前Activity是在同一个Task中的,则直接调用navigateUpTo()方法进行跳转,如果不是在同一个Task中的,则需要借助TaskStackBuilder来创建一个新的Task。
    这样,就按照标准的规范成功实现ActionBar导航的功能了。

    –效果图–

    这里写图片描述

  • 相关阅读:
    Java实现 LeetCode 56 合并区间
    JQuery实现对html结点的操作(创建,添加,删除)
    JQuery实现对html结点的操作(创建,添加,删除)
    JQuery实现对html结点的操作(创建,添加,删除)
    Java实现 LeetCode 55 跳跃游戏
    Java实现 LeetCode 55 跳跃游戏
    Java实现 LeetCode 55 跳跃游戏
    Java实现 LeetCode 54 螺旋矩阵
    Java实现 LeetCode 54 螺旋矩阵
    Java实现 LeetCode 54 螺旋矩阵
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467200.html
Copyright © 2011-2022 走看看