Android开发之ActionBar与DrawerLayout

本文详细介绍了在Android开发中如何使用ActionBar,包括它的功能、如何创建Actions、设置显示方式,以及处理ActionBar的点击事件。同时,文章还探讨了在低版本Android上使用ActionBar的支持方法。此外,文章还讲解了如何实现 DrawerLayout 抽屉效果,包括自定义主题、设置监听以及使用ActionBarDrawerToggle进行控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ActionBar位于Activity的顶部,可用来显示activity的标题、Icon、Actions和一些用于交互的View。它也可被用于应用的导航。
ActionBar 是在Android 3.0(API 11)中加入到SK中的,想在低版本中使用ActionBar给项目导入Support Library v7包即可。

使用ActionBar

开发API11以下的程序,首先必须在AndroidManifest.xml中指定Application或Activity的theme是Theme.Holo或其子类,否则将无法使用ActionBar。
如:

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.AppCompat.Light"
        android:name=".BaseApplication"
        >

2.1 创建Actions
Actions即ActionBar中的每个交互项,通常在XML文件中指定(位于res/menu)。在menu资源文件中定义Action的方法如下:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:wangxiapp="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
     tools:context=".MainActivity">
    <item android:id="@+id/action_search"
        android:icon="@mipmap/ic_action_search"  //搜索图标的图片
        android:title="research"        
        android:orderInCategory="100"  //此itemActionBar的位置。当有多个item时越大越在后面
        wangxiapp:showAsAction="ifRoom"
        />
</menu>

showAsAction属性用来定义每个Action是如何显示的,always表示永远显示在ActionBar中,如果屏幕空间不够则无法显示,ifRoom表示屏幕空间够的情况下显示在ActionBar中.
在Activity中创建ctionBar的Action代码位于onCreateOptionsMenu()中,下面一段代码展示了创建过程:

    @Override  
      public boolean onCreateOptionsMenu(Menu menu) {  
        MenuInflater inflater = getMenuInflater();  
        inflater.inflate(R.menu.mainmenu, menu);   //第一个参数设置ActionBar最左边的图片
        return true;  
      }   

有的时候由于一些特殊原因,最左边的图片,即应用的图标不显示,此时需要一些设置。在MainActivity中添加如下代码:

           actionBar = getSupportActionBar();
        actionBar.setLogo(R.mipmap.ic_launcher);
        actionBar.setDisplayUseLogoEnabled(true);
        actionBar.setDisplayShowHomeEnabled(true);

运行效果如图:

这里写图片描述

现在我们看到了设置的图片,但没有看的我们在item中设置的title。原因是:
如果你的menu既提供了title又提供了icon属性,那么默认显示icon,如果你想要显示文字title,就添加”withText”属性,如下:

1 <item yourapp:showAsAction="ifRoom|withText" ... />

备注:“withText”属性是给action bar的一个暗示,告诉它应该显示文字title,如果可以的话,就显示,但是当icon是可用的并且action bar的空间受到限制的时候,就不一定会显示了。

你应该为每一个item声明title属性,即使你不声明title要显示,因为:

1)如果没有足够的空间显示所有的action item,那显示在overflow中的Item就只会显示title,此时图片会变成竖着的三个点,点击时就会显示title;

2)视觉受损者会读取title;

3)如果action item只显示icon,那么当用户长按item的时候,会显示一个小的提示窗口显示action的title;

icon是可选的,但是推荐使用。

开发者可以使用”always”声明一个Item永远作为action button显示,但是开发者不应该用它迫使item用这种方式显示,在空间狭小的设备上,这会引起布局问题。最好的是使用”ifRoom”。这使得系统可以根据空间做出调整。只有当Item非常重要,关系到关键特征的时候,才可以使用”always”。

当点击右边搜索图片时设置监听:代码如下:

//布局做如下修改
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:wangxiapp="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
     tools:context=".MainActivity">
    <item android:id="@+id/action_search"
        android:icon="@mipmap/ic_action_search"
        android:title="@string/action_settings"
        android:orderInCategory="100"
        wangxiapp:showAsAction="ifRoom"
        wangxiapp:actionViewClass="android.support.v7.widget.SearchView"
        />
</menu>
//Activty如下操作
 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        //获取SearchView
        SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        //设置搜索的监听
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
          //当搜索提交的时候
            @Override
            public boolean onQueryTextSubmit(String query) {
                ToastUtil.showToast(UiUtil.getContext(), query);
                return true;
            }
         //当搜索文本改变的时候
            @Override
            public boolean onQueryTextChange(String newText) {
                ToastUtil.showToast(UiUtil.getContext(), newText);
                return true;
            }
        });
        return true;
    }

如果一个Action被单击,对于activity中的onOptionsItemSelected()将被调用。该函数的传入参数是一个MenuItem。通过判断该MenuItem的Id,即可确认是哪个Action被单击。现在我们通过这个事件来处理通过点击ActionBar的箭头来返回上一个Activity
这里写图片描述

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        android.support.v7.app.ActionBar actionBar =  getSupportActionBar();
        actionBar.setLogo(R.mipmap.ic_launcher);
        //显示返回主界面的箭头
        actionBar.setDisplayUseLogoEnabled(true);
        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setDisplayHomeAsUpEnabled(true);
    }
  //ActionBar的点击监听
   @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    //ActionBar的唯一id android.R.id.home
        if (item.getItemId()==android.R.id.home){
            finish();
        }
        return true;
    }

这样就可以在其他Activity中通过点击ActionBar来完成返回上个Activity。其实onOptionsItemSelected()这个可以在其他Activity中省略的。在清单文件中为该Activity设置(即可以完成点击Activty返回上个界面):

 <activity android:name=".DetailActivity"
            android:parentActivityName=".MainActivity"
            >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity"
                />
        </activity>

3 .实现ActionBar Tab标签
1 在Drawable 目录下 写了一个标签的状态选择器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- STATES WHEN BUTTON IS NOT PRESSED -->

    <!-- Non focused states -->
    <item android:state_focused="false" android:state_selected="false"
        android:state_pressed="false"
        android:drawable="@mipmap/tab_unselected" />
    <item android:state_focused="false" android:state_selected="true"
        android:state_pressed="false"
        android:drawable="@mipmap/tab_selected" />

    <!-- Focused states (such as when focused with a d-pad or mouse hover) -->
    <item android:state_focused="true" android:state_selected="false"
        android:state_pressed="false"
        android:drawable="@mipmap/tab_unselected_focused" />
    <item android:state_focused="true" android:state_selected="true"
        android:state_pressed="false"
        android:drawable="@mipmap/tab_selected_focused" />

    <!-- STATES WHEN BUTTON IS PRESSED -->

    <!-- Non focused states -->
    <item android:state_focused="false" android:state_selected="false"
        android:state_pressed="true"
        android:drawable="@mipmap/tab_unselected_pressed" />
    <item android:state_focused="false" android:state_selected="true"
        android:state_pressed="true"
        android:drawable="@mipmap/tab_selected_pressed" />

    <!-- Focused states (such as when focused with a d-pad or mouse hover) -->
    <item android:state_focused="true" android:state_selected="false"
        android:state_pressed="true"
        android:drawable="@mipmap/tab_unselected_pressed" />
    <item android:state_focused="true" android:state_selected="true"
        android:state_pressed="true"
        android:drawable="@mipmap/tab_selected_pressed" />
</selector>

2 实现自定义主题 (在values下创建resources)

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
         <!-- the theme applied to the application or activity -->
        <style name="CustomActionBarTheme"
               parent="@style/Theme.AppCompat.Light">
        <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item> 

            <!-- Support library compatibility -->
            <item name="actionBarTabStyle">@style/MyActionBarTabs</item>
        </style>

        <!-- ActionBar tabs styles -->
        <style name="MyActionBarTabs"
               parent="@style/Widget.AppCompat.ActionBar.TabView">
            <!-- tab indicator -->
            <item name="android:background">@drawable/actionbar_tab_indicator</item>

            <!-- Support library compatibility -->
            <item name="background">@drawable/actionbar_tab_indicator</item>
        </style>
    </resources>

3.在Activity中设置:

      ActionBar actionBar = getSupportActionBar();
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
     ActionBar.Tab tab1 = actionBar.newTab().setText("标签一").setTabListener(new MyTabListener());
     actionBar.addTab(tab1);
     ActionBar.Tab tab2 = actionBar.newTab().setText("标签二").setTabListener(new MyTabListener());
     actionBar.addTab(tab2);
     ActionBar.Tab tab3 = actionBar.newTab().setText("标签三").setTabListener(new MyTabListener());
     actionBar.addTab(tab3);
     ActionBar.Tab tab4 = actionBar.newTab().setText("标签四").setTabListener(new MyTabListener());
     actionBar.addTab(tab4);

这里写图片描述

DrawerLayout (抽屉效果):

    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" 
        android:id="@+id/dl">

        <LinearLayout
        //这里的LinearLayout是一开始是看见的主布局
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
           />

        <FrameLayout
               //这个布局就是抽屉,即通过测拉才可以显示的布局
                android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/bg_tab"
            //抽屉在左边
            android:layout_gravity="left">

        </FrameLayout>
    </android.support.v4.widget.DrawerLayout>

给抽屉设置监听:
这里写图片描述

ActionBarDrawerToggle :
控制抽屉的开关, 显示在actionBar 上面 (即通过点击就可以打开和关闭抽屉):

 ActionBar actionBar = getSupportActionBar();
 //设置显示ActionBar的点击图标没,如下图的最左边的图标
actionBar.setDisplayHomeAsUpEnabled(true);
     actionBar.setHomeButtonEnabled(true);
 DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
     actionBarDrawerToggle = new ActionBarDrawerToggle(MainActivity.this, drawerLayout, R.string.app_name, R.string.app_name){
          // 创建时就可以设置抽屉的监听。关闭监听
         @Override
         public void onDrawerClosed(View drawerView) {
             super.onDrawerClosed(drawerView);
             ToastUtil.showToast(MainActivity.this,"close");
         }
           //开启监听
         @Override
         public void onDrawerOpened(View drawerView) {
             super.onDrawerOpened(drawerView);
             ToastUtil.showToast(MainActivity.this, "open");
         }
     };
     //  让开关和Actionbar建立关系 
     actionBarDrawerToggle.syncState();
        //设置监听
     drawerLayout.setDrawerListener(actionBarDrawerToggle);

        /** 处理actionBar菜单条目的点击事件 */
        public boolean onOptionsItemSelected(MenuItem item) {
            if (item.getItemId() == R.id.action_search) {
                Toast.makeText(getApplicationContext(), "搜索", 0).show();
            }
    //返回值很重要
            return drawerToggle.onOptionsItemSelected(item)|super.onOptionsItemSelected(item);
        }

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值