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导航的功能了。

    –效果图–

    这里写图片描述

  • 相关阅读:
    Linux dd 命令
    excel合并单元格数据读取
    判断字符串是否以中文字符开头
    列表嵌套字典去重统计
    【转载】【DBDK】dpdk大页内存原理
    【LinuxShell】ps 命令浅析
    【LinuxShell】free 命令详解
    【网络安全】IOC概念浅析
    【转载】【网络安全】渗透中 PoC、Exp、Payload 与 Shellcode 的区别
    【SVN】windows 下的SVN常见问题及其解决方法
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467200.html
Copyright © 2011-2022 走看看