ActionBar简单使用——添加搜索按钮;让不同的Activity上显示不同的ActionBar;添加Tab标签;实现DrawerLayout并用ActionBarDrawerToggle控制

来源:互联网 发布:移动端ui框架 知乎 编辑:程序博客网 时间:2024/06/05 08:31
  • 什么是ActionBar
    • Android3.0以后出现的一个API专门用来开发应用顶部的ActionBar
    • 他是一个显示在屏幕顶部的控件,它可以在顶部的左边显示应用的logo图标和右边的一些操作菜单(如:搜索)
    • Google攻城狮在开发ActionBar API的同时,也开发了好多辅助功能,比如抽屉,可以在顶部控制抽屉的开关;Tab标签;等等,下面会介绍一些常用的功能;

创建ActionBar

  • 由于ActionBar是Android3.0之后出现的API,所以,默认只最低兼容3.0以上的设备。即在AndroidManifest.xml配置文件中,我们配置的最低版本号应为11
<manifest ... >    <uses-sdk android:minSdkVersion="11" ... />    ...</manifest>
  • 但是想兼容3.0以下2.1以上的也不是不可以,哈哈哈,但是需要引入一个V7 appcompat libryary包。和V4包有点像,但他两一点关系也没有,别混淆。这个包在我们的SDK的目录下已经有了"开发工具安装根目录\sdk\extras\android\m2repository\com\android\support" 不过这个我感觉用着不爽,这个还行,可以在里面看到源码V7 appcompat libryary免费下载地址
    • 如何给当前项目添加支持库(添加libryary包):
      1. 将V7包解压后,Import进我们的eclipse中;
      2. 然后,在我们当前项目名上点击右键;
      3. 在弹出的右键菜单中,选择倒数第二个的”Properties”(左键点击项目名后直接按Alt+Enter键也可以);
      4. 接下来,在左边的条目栏中选择第二个”Android”;
      5. 在右边的窗口中,下拉到最底部;
      6. 在Library模块下选择ADD,在弹出的对话框中选择”android-support-v7-appcompat”;
      7. 然后一路点击OK就可以了。
      8. 注意应如后有可能会有V4包的版本冲突,将两个工程都调成一样的就可以了
  • 我们导入了V7包之后就可以正式进行ActionBar的创建了
    1. 在MainActivity中继承ActionBarActivity
    2. 在AndroidManifest.xml文件中修改主题

      在application标签下,吧android:theme=”“中的值设为Theme.AppCompat主题中的一个,我们选择<activity android:theme="@style/Theme.AppCompat.Light" ... >
      现在一个简单的ActionBar就建成功了:
      ActionBar创建成功


接下来我们将对其进行一步步的定制

ActionBar搜索按钮

  • 在上面的图片中,可以看到右上角是一个菜单键,点击会弹出菜单项。所以,这其实就是菜单按钮
    一、配置main.xml:到res文件夹下的menu文件夹里的main.xml文件里,是在那定义了菜单键,我在教程上拷贝如下代码:
<menu xmlns:android="http://schemas.android.com/apk/res/android" ><!-- Search, should appear as action button(搜索键的配置) --><item android:id="@+id/action_search"    android:icon="@drawable/ic_action_search"    android:title="@string/action_search"    android:showAsAction="ifRoom" /><!-- Settings, should always be in the overflow(设置键的配置) --><item android:id="@+id/action_settings"      android:title="@string/action_settings"      android:showAsAction="never" /></menu>

在上面的代码块中,第一个Item是配置搜索键的,第二个Item是配置设置键的,我们只想要看到搜索键,所以把第二个删掉。但是这只是从官方教程上拷贝下来的,要想符合我们的要求还需进一步配置
1. 添加我们的自定义命名空间:xmlns:actionBar="http://schemas.android.com/apk/res-auto"
2. 将android:showAsAction="ifRoom"改为actionBar:showAsAction="ifRoom
3. 在Item中添加一个V7包的配置:android:actionViewClass="android.support.v7.widget.SearchView"
最终的manu.xml配置文件

<menu xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:actionBar="http://schemas.android.com/apk/res-auto" >    <!-- Search, should appear as action button -->    <item android:id="@+id/action_search"          android:icon="@drawable/ic_action_search"          android:title="@string/action_search"          actionBar:showAsAction="ifRoom"          actionBar:actionViewClass="android.support.v7.widget.SearchView" /></menu>

二、初始化菜单并添加逻辑

// 初始化菜单并添加逻辑@SuppressLint("NewApi")@Overridepublic boolean onCreateOptionsMenu(Menu menu) {    // Inflate the menu; this adds items to the action bar if it is present.    getMenuInflater().inflate(R.menu.main, menu);    // "版本的控制",如果低于3.0版本的就不执行此方法    if(android.os.Build.VERSION.SDK_INT > 11){        SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();        searchView.setOnQueryTextListener(this);// 搜索的监听    }    return true;}

三、处理ActionBar 菜单条目的点击事件:在Activity中添加代码

/** * 处理ActionBar的菜单条目的点击事件,以后所有在ActionBar上的东西, * 都需要在这里处理一下 */@Overridepublic boolean onOptionsItemSelected(MenuItem item){    // Handle presses on the action bar items    if(item.getItemId() == R.id.action_search){        Toast.makeText(getApplicationContext(), "搜索", 0).show();    }    return super.onContextItemSelected(item);}

三、 查询:在MainActivity中需要实现OnQueryTextListener类

  • 同时需要实现两个方法

    • onQueryTextSubmit()

      @Overridepublic boolean onQueryTextSubmit(String query) {    Toast.makeText(getApplicationContext(), "搜索提交", 0).show();    return true;}
    • 介绍:

    Called when the user submits the query. 当用户提交数据时调用
    Returns:true if the query has been handled by the listener, false to let the SearchView perform the default action.(当查询已经被监听时返回true,默认情况下返回false,不会查询)

    • onQueryTextChange()

      @Overridepublic boolean onQueryTextChange(String newText) {    Toast.makeText(getApplicationContext(), "文本改变", 0).show();    return true;}
    • 介绍:

      Called when the query text is changed by the user.当查询文本改变时被调用
      Returns:false if the SearchView should perform the default action of showing any suggestions if available, true if the action was handled by the listener.和上面的方法一样

MainActivity.java

package com.example.actionbar;import android.os.Bundle;import android.annotation.SuppressLint;import android.support.v7.app.ActionBarActivity;import android.support.v7.widget.SearchView;import android.support.v7.widget.SearchView.OnQueryTextListener;import android.view.Menu;import android.view.MenuItem;import android.widget.Toast;public class MainActivity extends ActionBarActivity implements OnQueryTextListener {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    // 初始化菜单并添加逻辑    @SuppressLint("NewApi")    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        if(android.os.Build.VERSION.SDK_INT > 11){            SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();            searchView.setOnQueryTextListener(this);// 搜索的监听        }        return true;    }    /**     * 处理ActionBar的菜单条目的点击事件     */    @Override    public boolean onOptionsItemSelected(MenuItem item){        // Handle presses on the action bar items        if(item.getItemId() == R.id.action_search){            Toast.makeText(getApplicationContext(), "搜索", 0).show();        }        return super.onContextItemSelected(item);    }    // 当搜索提交的时候        @Override        public boolean onQueryTextSubmit(String query) {            Toast.makeText(getApplicationContext(), query, 0).show();            return true;        }        // 当文本发生变化时        @Override        public boolean onQueryTextChange(String newText) {            Toast.makeText(getApplicationContext(), newText, 0).show();            return true;        }}

这时,运行代码,右上角会出现搜索图标,点击文本域,可以响应
下面进行详情页的配置

DetailActivity 详情页面的配置

  • 我们在包里重新建一个类DetailActivity.java
package com.example.actionbar;import android.os.Bundle;import android.support.v7.app.ActionBar;import android.support.v7.app.ActionBarActivity;import android.view.View;public class DetailActivity extends ActionBarActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 设置布局        setContentView(R.layout.activity_detail);    }    public void click(View v){        finish();    }}
  • 新建一个布局文件main_detail.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <Button        android:onClick="click"        android:id="@+id/button1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Button" /></LinearLayout>
  • 在main_activity.xml文件中添加一个Button,并在MainActivity.java中进行配置,使得其通过点击就可以跳转到DetailActivity
    • 在MainActivity中添加的代码

      public void click(View v){
      Intent intent = new Intent(getApplicationContext(), DetailActivity.class);
      startActivity(intent);
      }
    • main_activity.xml文件中添加一个Button

      <Button
      android:onClick="click"
      android:id="@+id/button1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_below="@+id/textView1"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="140dp"
      android:text="跳转到DetailActivity" />

注意:在清单文件中,需要对Activity进行配置一下
<activity android:name=".DetailActivity">
</activity>

  • 现在我们通过点击Button就可以跳转到详情页了。下面,进行详情页的配置。

让不同的Activity上面显示不同的ActionBar

  • 只需在清单文件中,在对Activity进行配置的下面,添加一个label就可以了
    详情页标签

给详情页面添加返回键

  • 首先在DetailActivity中要得到ActionBar
  • 然后对ActionBar使用setDisplayHomeAsUpEnabled(true)
  • 这样在详情页面的ActionBar上的左端,就会显示返回键;
    • 对返回键的获取
      • 固定的写法:android.R.id.home
  • 这样更方便用户操作我们的应用程序
  • DetailActivity.java
package com.example.actionbar;import android.os.Bundle;import android.support.v7.app.ActionBar;import android.support.v7.app.ActionBarActivity;import android.view.MenuItem;import android.view.View;import android.widget.Toast;public class DetailActivity extends ActionBarActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 设置布局        setContentView(R.layout.activity_detail);        // 显示返回键        ActionBar actionBar = getSupportActionBar();        actionBar.setDisplayHomeAsUpEnabled(true);    }    public void click(View v){        finish();    }    /**     * 处理ActionBar菜单条目的点击事件--返回键     */    @Override    public boolean onOptionsItemSelected(MenuItem item) {        if(item.getItemId() == android.R.id.home){            finish();        }        return super.onContextItemSelected(item);    }}

添加返回键

虽然在activity中可以对返回键进行操作,但是,我们还有另外一个方法

  • 在AndroidManifest.xml文件中给DetailActivity配置一个”爹”
<!-- The main/home activity (it has no parent activity) --><activity android:name="com.example.actionbar.MainActivity"        android:label="@string/app_name" >        <intent-filter>            <action android:name="android.intent.action.MAIN" />            <category android:name="android.intent.category.LAUNCHER" />        </intent-filter></activity><!-- A child of the main activity --><activity android:name=".DetailActivity"        android:label="@string/detail"    android:parentActivityName="com.example.actionbar.MainActivity" >     <!-- Parent activity meta-data to support 4.0 and lower(兼容性配置,不可少) -->     <meta-data                android:name="android.support.PARENT_ACTIVITY"                android:value="com.example.actionbar.MainActivity" /></activity>
  • 这时,DetailActivity中就可以不用写那段代码,也可以实现返回功能

给ActionBar添加Tab标签

  1. 在Drawable目录下,写一个标签的状态选择器actionbar_tab_indicator.xml,代码直接从官方教程中考过来

    <?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="@drawable/tab_unselected" />    <item android:state_focused="false" android:state_selected="true"          android:state_pressed="false"          android:drawable="@drawable/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="@drawable/tab_unselected_focused" />    <item android:state_focused="true" android:state_selected="true"          android:state_pressed="false"          android:drawable="@drawable/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="@drawable/tab_unselected_pressed" />    <item android:state_focused="false" android:state_selected="true"        android:state_pressed="true"        android:drawable="@drawable/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="@drawable/tab_unselected_pressed" />    <item android:state_focused="true" android:state_selected="true"          android:state_pressed="true"          android:drawable="@drawable/tab_selected_pressed" /></selector>
  2. 自定义主题,theme.xml

    <?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. 在清单文件中,应用我们的自定义主题,就是前面定义主题的地方

    android:theme="@style/CustomActionBarTheme"
  4. 在MainActivity中获取ActionBar,对其设置导航条

    ActionBar actionBar = getSupportActionBar();actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);Tab tab1 = actionBar.newTab().setText("标签1").setTabListener(new MyTabListener());actionBar.addTab(tab1);Tab tab2 = actionBar.newTab().setText("标签1").setTabListener(new MyTabListener());actionBar.addTab(tab2);Tab tab3 = actionBar.newTab().setText("标签1").setTabListener(new MyTabListener());actionBar.addTab(tab3);
  5. 要创建一个方法,实现TabListener方法

    public class MyTabListener implements TabListener{        @Override        public void onTabReselected(Tab arg0, FragmentTransaction arg1) {        }        @Override        public void onTabSelected(Tab arg0, FragmentTransaction arg1) {        }        @Override        public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {        }    }

    Tab标签

DrawerLayout API

  • 这个可以实现抽屉效果的导航菜单,感觉用起来比SlidingMenu方便多了。
  • 属于android.support.v4.widget.DrawerLayout下面,只需将这个全类名拷贝至相对应的布局文件中,就可使用抽屉效果
    main_activity.xml
<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" >    <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:layout_gravity="left"        android:background="@drawable/bg_tab" >    </FrameLayout>    <!-- <TextView        android:id="@+id/textView1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello_world" />    <Button        android:onClick="click"        android:id="@+id/button1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@+id/textView1"        android:layout_centerHorizontal="true"        android:layout_marginTop="140dp"        android:text="跳转到DetailActivity" /> --></android.support.v4.widget.DrawerLayout>

抽屉式侧拉菜单

ActionBarDrawerToggle

控制抽屉的开关,显示在ActionBar上

  1. 显示开关

    ActionBar actionBar = getSupportActionBar();actionBar.setDisplayHomeAsUpEnabled(true);actionBar.setHomeButtonEnabled(true);
  2. 创建DrawerToggle,并进行一些配置

    // 参数1 当前actionBar所在的activity 参数2 控制是哪个抽屉// 参数3 抽屉按钮的图片 参数4 抽屉打开的描述 drawerToggle = new ActionBarDrawerToggle(this,        mDrawerLayout, R.drawable.ic_drawer_am, R.string.open_drawer, R.string.close_drawer){        // 当抽屉完全关闭时被调用        @Override        public void onDrawerClosed(View drawerView){            super.onDrawerClosed(drawerView);            Toast.makeText(getApplicationContext(), "抽屉打开了", 0).show();        }        // 当抽屉完全打开时被调用        @Override        public void onDrawerOpened(View drawerView){            super.onDrawerClosed(drawerView);            Toast.makeText(getApplicationContext(), "抽屉关闭了", 0).show();        }    };    // 让开关和Actionbar建立关系    drawerToggle.syncState();    // 设置监听    mDrawerLayout.setDrawerListener(drawerToggle);
  3. 别忘记处理菜单条目上处理DrawerToggle

    /** * 处理ActionBar菜单条目的点击事件--搜索 */@Overridepublic boolean onOptionsItemSelected(MenuItem item) {    // Handle presses on the action bar items    if(item.getItemId() == R.id.action_search){        Toast.makeText(getApplicationContext(), "搜索", 0).show();    }    return drawerToggle.onOptionsItemSelected(item)|super.onContextItemSelected(item);}

    MainActivity.java

package com.example.actionbar;import android.os.Bundle;import android.annotation.SuppressLint;import android.support.v4.app.ActionBarDrawerToggle;import android.support.v4.app.FragmentTransaction;import android.support.v4.widget.DrawerLayout;import android.support.v7.app.ActionBar;import android.support.v7.app.ActionBar.Tab;import android.support.v7.app.ActionBar.TabListener;import android.support.v7.app.ActionBarActivity;import android.support.v7.widget.SearchView;import android.support.v7.widget.SearchView.OnQueryTextListener;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Toast;public class MainActivity extends ActionBarActivity implements OnQueryTextListener {    private DrawerLayout mDrawerLayout;    private ActionBarDrawerToggle drawerToggle;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ActionBar actionBar = getSupportActionBar();        actionBar.setDisplayHomeAsUpEnabled(true);        actionBar.setHomeButtonEnabled(true);        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);        Tab tab1 = actionBar.newTab().setText("标签1").setTabListener(new MyTabListener());        actionBar.addTab(tab1);        Tab tab2 = actionBar.newTab().setText("标签2").setTabListener(new MyTabListener());        actionBar.addTab(tab2);        Tab tab3 = actionBar.newTab().setText("标签3").setTabListener(new MyTabListener());        actionBar.addTab(tab3);        mDrawerLayout = (DrawerLayout) findViewById(R.id.dl);        // 参数1 当前actionBar所在的activity 参数2 控制是哪个抽屉        // 参数3 抽屉按钮的图片 参数4 抽屉打开的描述         drawerToggle = new ActionBarDrawerToggle(this,                mDrawerLayout, R.drawable.ic_drawer_am, R.string.open_drawer,                 R.string.close_drawer){            // 当抽屉完全关闭时被调用            @Override            public void onDrawerClosed(View drawerView){                super.onDrawerClosed(drawerView);                Toast.makeText(getApplicationContext(), "抽屉关闭了", 0).show();            }            // 当抽屉完全打开时被调用            @Override            public void onDrawerOpened(View drawerView){                super.onDrawerClosed(drawerView);                Toast.makeText(getApplicationContext(), "抽屉打开了", 0).show();            }        };        // 让开关和Actionbar建立关系        drawerToggle.syncState();        // 设置监听        mDrawerLayout.setDrawerListener(drawerToggle);    }    // 初始化菜单并添加逻辑    @SuppressLint("NewApi")    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        if(android.os.Build.VERSION.SDK_INT > 11){            SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();            searchView.setOnQueryTextListener(this);// 搜索的监听        }        return true;    }    public class MyTabListener implements TabListener{        @Override        public void onTabReselected(Tab arg0, FragmentTransaction arg1) {        }        @Override        public void onTabSelected(Tab arg0, FragmentTransaction arg1) {        }        @Override        public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {        }    }    /*public void click(View v){        Intent intent = new Intent(getApplicationContext(), DetailActivity.class);        startActivity(intent);    }*/    /**     * 处理ActionBar的菜单条目的点击事件     */    @Override    public boolean onOptionsItemSelected(MenuItem item){        // Handle presses on the action bar items        if(item.getItemId() == R.id.action_search){            Toast.makeText(getApplicationContext(), "搜索", 0).show();        }        return drawerToggle.onOptionsItemSelected(item)|super.onContextItemSelected(item);    }    // 当搜索提交的时候        @Override        public boolean onQueryTextSubmit(String query) {            Toast.makeText(getApplicationContext(), query, 0).show();            return true;        }        // 当文本发生变化时        @Override        public boolean onQueryTextChange(String newText) {            Toast.makeText(getApplicationContext(), newText, 0).show();            return true;        }}

DrawerToggle


项目源码


推荐一个学习Android比较好的网址

android开发官方文档国内镜像——wear.techbrood.com点击访问

0 0