Android学习之界面篇(七)侧滑菜单的实现

侧滑菜单的实现方式:

  1. SlidingMenu开源库:https://github.com/jfeinstein10/SlidingMenu
  2. DrawerLayout:是2013年谷歌IO大会上由谷歌官方发布的,包含在support v4包中。

官方定义:http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html

使用说明:http://developer.android.com/training/implementing-navigation/nav-drawer.html

接下来按照谷歌官方给定的创建步骤来实现一个侧滑菜单。


Create a Drawer Layout


To add a navigation drawer, declare your user interface with aDrawerLayout object
as the root view of your layout.

Inside theDrawerLayout,
add one view that contains the main content for the screen (your primary layout when the drawer is hidden) and another view that contains the contents of the navigation drawer.

按照谷歌官方给出的示例创建一个带有Drawer Layout的项目:

activity_main.xml配置如下:

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

    <!--The main content view-->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/content_frame">

    </FrameLayout>

    <!--The navigation view-->
    <ListView
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:id="@+id/left_drawer"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:background="#ffffcc"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp">

    </ListView>

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

启动项目,通过从屏幕左端滑动来滑出菜单。

注:

android:layout_gravity="start"是从屏幕左边滑动,"end"则为从屏幕右端滑出。

android:choiceMode="singleChoice"模式为单选模式

android:divider="@android:color/transparent"分割线采用原始的透明分割线

android:dividerHeight="0dp"分割线高度为0,不可见。

注意事项:

  1. 主内容视图一定要是DrawerLayout的第一个子视图
  2. 主内容视图宽度高度要匹配父视图,即"match_parent",也就是说:当抽屉隐藏时,要让用户看到主视图的全部内容。
  3. 必须显示指定抽屉视图(如LiistView)的android:layout_gravity属性。
  • android:layout_gravity="start"从左向右滑出菜单
  • android:layout_gravity="end"从右向左滑出菜单
  • 不推荐使用"left" 和"right"

4.抽屉视图的宽度以dp为单位,请不要超过320dp(为了总能看到一些主内容视图)


Initialize the Drawer List


In your activity, one of the first things to do is initialize the navigation drawer‘s list of items. How you do so depends on the content of your app, but a navigation drawer often consists of a ListView,
so the list should be populated by an Adapter (such
as ArrayAdapter or SimpleCursorAdapter).

接下来在项目中实现初始化Drawer List的操作。

1.首先对组件进行声明,包括DrawerLayout和ListView。

private DrawerLayout mDrawerLayout;

private ListView mDrawerList;

2.使用ArrayList集合来储存菜单项,使用ArrayAdapter对ListView的内容进行填充。

//使用集合来储存侧滑菜单的菜单项

private ArrayList<String> menuLists;

//使用ArrayAdapter来对ListView的内容进行填充

private ArrayAdapter<String> adapter;

3.在onCreate方法中对z组件进行查找和初始化数据操作。

mDrawerLayout= (DrawerLayout) findViewById(R.id.draw_layout);

mDrawerList= (ListView) findViewById(R.id.left_drawer);

//初始化menulists

menuLists=new ArrayList<String>();

for (int i=0;i<5;i++){

menuLists.add("测试菜单"+i);

}

//初始化adapter

adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,menuLists);

//为侧边菜单填充上内容

mDrawerList.setAdapter(adapter);


Handle Navigation Click Events


When the user selects an item in the drawer‘s list, the system calls onItemClick() on
theOnItemClickListener given
to setOnItemClickListener().

What you do in the onItemClick() method depends on how you‘ve implemented your app
structure
.

1.为菜单项添加点击事件监听器,并让主类实现事件监听器接口

mDrawerList.setOnItemClickListener(this);

2.复写事件监听器中的方法,动态插入一个Fragment到FrameLayout中去

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

//动态插入一个Fragment到FrameLayout当中

Fragment contentFragment=new ContentFragment();

Bundle args=new Bundle();

args.putString("text",menuLists.get(position));

contentFragment.setArguments(args);//?

//新建一个Fragment

FragmentManager fm=getFragmentManager();

fm.beginTransaction().replace(R.id.content_frame,contentFragment).commit();

//点击完成后关闭菜单栏

mDrawerLayout.closeDrawer(mDrawerList);

}

3.新建一Fragment ContentFragment,对应配置文件为fragment_content.xml

fragment_content.xml配置如下:

<FrameLayout 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"

android:id="@+id/content_frame"

tools:context="com.example.icarus.drawerlayoutusing.ContentFragment">

<!-- TODO: Update blank fragment layout -->

<TextView

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:id="@+id/textView"

android:textSize="25sp"

/>

</FrameLayout>

ContentFragment.java具体代码:

public class ContentFragment extends Fragment {

private TextView textView;

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

//动态加载视图

View view=inflater.inflate(R.layout.fragment_content,container,false);

//查找组件id

textView= (TextView) view.findViewById(R.id.textView);

//通过Arguments来传递数据

String text=getArguments().getString("text");

//给textview设置文字

textView.setText(text);

//返回加载的视图

return view;

}

}


问题:

1. 为什么要用Fragment.setArguments(Bundle
bundle)来传递参数
 ?

Activity重新创建时,会重新构建它所管理的Fragment,原先的Fragment的字段值将会全部丢失,但是通过Fragment.setArguments(Bundle
bundle)方法设置的bundle会保留下来。所以尽量使用Fragment.setArguments(Bundle bundle)方式来传递参数

具体:http://blog.csdn.net/tu_bingbing/article/details/24143249


Listen for Open and Close Events


To listen for drawer open and close events, call setDrawerListener() on
your DrawerLayout and pass it an implementation of DrawerLayout.DrawerListener.
This interface provides callbacks for drawer events such asonDrawerOpened() and onDrawerClosed().

However, rather than implementing the DrawerLayout.DrawerListener,
if your activity includes the action bar, you can instead extend the ActionBarDrawerToggle class.
The ActionBarDrawerToggle implementsDrawerLayout.DrawerListener so
you can still override those callbacks, but it also facilitates the proper interaction behavior between the action bar icon and the navigation drawer (discussed further in the next section).

As discussed in the Navigation
Drawer
 design guide, you should modify the contents of the action bar when the drawer is visible, such as to change the title and remove action items that are contextual to the main content.

知识点介绍:

1.mDrawerLayout.setDrawerListener(DrawerLayout.DrawerListener);

2.ActionBarDrawerToggle是 DrawerLayout.DrawerListener的具体实现类。

   1)改变android.R.id.home图标(构造方法)

   2)Drawer拉出、隐藏,带有android.R.id.home动画效果(syncState())

   3)监听Drawer拉出、隐藏事件

3.复写ActionBarDrawerToggle的onDrawerOpended()和onDrawerClosed()以监听抽屉拉出或隐藏事件。

4.复写Activity中的onPostCreate()方法和onConfigurationChange()方法,是为了结合syncState()方法来s实现左上角图标动画的效果。当设备的y一些参数发生变化时(屏幕旋转等)就会调用onConfigurationChange方法,在方法中对ActionBarDrawerToggle进行配置。


在代码中实现:

(一)设置菜单被拉出时Title文字的改变

1.首先声明一个ActionBarDrawerToggle,注意是support.v7包中的(support.v4包中的已经失效)

使用v7替换v4方法请看:ActionBarDrawerToggle
is Deprecated

private ActionBarDrawerToggle mDrawerToggle;

2.接着初始化ActionBarDrawerToggle,(具体参数为:ActionBarDrawerToggle(Activity activity,

DrawerLayout drawerLayout,
int openDrawerContentD

escRes, int closeDrawerContentDescRes))并复写其中的onDrawerOpended()和onDrawerClosed()方法来实现拉出或隐藏抽屉时对Title的更改。

注:使用v7包的时候得使用getSupportActionBar()来设置Title信息

mDrawerToggle=new ActionBarDrawerToggle(this,mDrawerLayout,

R.string.drawer_open,R.string.drawer_close){

/**

     * 当抽屉被打开是执行

     设置抽屉被打开时的Title

     * 通过getActionBar()来改变

     @param drawerView

     */

    @Override

public void onDrawerOpened(View drawerView) {

super.onDrawerOpened(drawerView);

//BUG:此处产生空指针异常,使用getSupportActionBar()

//getActionBar().setTitle("请选择");

getSupportActionBar().setTitle("请选择");

invalidateOptionsMenu();//重绘actionbar上的菜单项,会自动调用onPrepareOptionsMenu方法

}

/**

     * 当抽屉被关闭时执行

     设置抽屉被关闭时的Title

     * @param drawerView

     */

    @Override

public void onDrawerClosed(View drawerView) {

super.onDrawerClosed(drawerView);

getSupportActionBar().setTitle(mTitle);

invalidateOptionsMenu();//重绘actionbar上的菜单项

}

};

3.给DrawerLayout添加DrawerListener。setDrawerListener以失效,使用addDrawerListener

mDrawerLayout.addDrawerListener(mDrawerToggle);


(二)在ActionBar上添加搜索图标

1.在res中新建menu文件夹,在其中添加main.xml,其中

android:showAsAction。

  这个属性可接受的值有:

  1、always:这个值会使菜单项一直显示在Action Bar上。

  2、ifRoom:如果有足够的空间,这个值会使菜单项显示在Action Bar上。

  3、never:这个值使菜单项永远都不出现在Action Bar上。

  4、withText:这个值使菜单项和它的图标,菜单文本一起显示。

main.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_websearch"

android:icon="@drawable/action_search"

android:title="webSearch"

app:showAsAction="ifRoom|withText"/>

</menu>

2.在MainActivity中使用onCreateOptionsMenu()来加载menu

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.main,menu);

return true;

}

3.在执行invalidateOptionsMenu()方法时会调用onPrepareOptionsMenu(),复写此方法来实现菜单图标的显示状态。首先先获取Drawer的打开状态,当Drawer打开时菜单图标被隐藏,当Drawer关闭时显示菜单图标。即菜单图标的显示状态与Drawer的打开状态正好相反。

public boolean onPrepareOptionsMenu(Menu menu) {

//获取Drawer的打开状态

boolean isDrawerOpen=mDrawerLayout.isDrawerOpen(mDrawerList);

//对menuItem的可见状态进行改变,总是跟Drawer的打开状态相反

menu.findItem(R.id.action_websearch).setVisible(!isDrawerOpen);

return super.onPrepareOptionsMenu(menu);

}

4.使用onOptionsItemSelected()方法来为菜单项设置点击事件。让其使用系统浏览器打开指定的网页(百度)。

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.action_websearch:

Intent intent=new Intent();

intent.setAction("android.intent.action.VIEW");

Uri uri=Uri.parse("http://www.baidu.com");

intent.setData(uri);

startActivity(intent);

break;

}

return super.onOptionsItemSelected(item);

}


Open and Close with the App Icon


Users can open and close the navigation drawer with a swipe gesture from or towards the left edge of the screen, but if you‘re using the action
bar
, you should also allow users to open and close it by touching the app icon. And the app icon should also indicate the presence of the navigation drawer with a special icon. You can implement all this behavior by using the ActionBarDrawerToggle shown
in the previous section.

To make ActionBarDrawerToggle work,
create an instance of it with its constructor, which requires the following arguments:

  • The Activity hosting the drawer.
  • The DrawerLayout.
  • A drawable resource to use as the drawer indicator.

    The standard navigation drawer icon is available in the Download
    the Action Bar Icon Pack
    .
  • A String resource to describe the "open drawer" action (for accessibility).
  • A String resource to describe the "close drawer" action (for accessibility).

Then, whether or not you‘ve created a subclass of ActionBarDrawerToggle as
your drawer listener, you need to call upon your ActionBarDrawerToggle in
a few places throughout your activity lifecycle:

我们希望使用app的图标来打开和关闭侧边栏,根据谷歌开发者文档

1.首先打开ActionBar Icon的功能

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

2.使左上角的Home-Button可用,因为左上角的Home-Button也属于menu的一种所以点击时会回调onOptionItemSelected方法。

getSupportActionBar().setHomeButtonEnabled(true);

3.在 onOptionItemSelected方法中将ActionBar上的图标与Drawer结合起来。

if (mDrawerToggle.onOptionsItemSelected(item)){

return true;

}

4.需要将ActionDrawerToggler与DrawerLayout的状态同步 ,将ActionBarDrawerTaggler中的drawer图标,设置为ActionBar中的Home-Button的icon

public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {

super.onPostCreate(savedInstanceState, persistentState);

mDrawerToggle.syncState();

}

5.谷歌开发者文档建议使用onConfigurationChanged方法 ,当屏幕旋转等发生Configuration变化的时候执行

public void onConfigurationChanged(Configuration newConfig) {

super.onConfigurationChanged(newConfig);

mDrawerToggle.onConfigurationChanged(newConfig);

}


到此,我们使用谷歌开发者文档提供的DrawerLayout成功完成了侧滑菜单的开发!

项目源码下载:

https://github.com/icaruswang/DrawerLayoutUsing

时间: 2024-10-11 13:38:28

Android学习之界面篇(七)侧滑菜单的实现的相关文章

Android学习之界面篇(九)SurfaceView简单学习

知识点: surfaceview介绍 surfaceview与View的区别,surface与surfaceview的区别 实例创建与使用 SurfaceHolder.Callback的使用,surfaceHolder可以看作是surfaceview的控制器,控制图形的大小,像素等. 在主函数中回调函数的使用getHolder.addCallback(this) canvas的锁定与解锁,绘制图形之前锁定画布,绘制结束之后解锁画布. canvas的save与restore, canvas画布的各

Android学习之——优化篇(2)

一.高级优化 上篇主要从初级优化的方式,本篇主要将从程序运行性能的角度出发,分析各种常用方案的不足,并给出对象池技术.基础数据类型替换法.屏蔽函数计算三种能够节省资源开销和处理器时间的优化策略. 目前普遍采用的优化方案有:     · 优化循环,通过重新组织重复的子表达式来提高循环体的运行性能     · 减少使用对象的数量来提高运行性能     · 缩减网络传输数据来缩短等待时间等 本篇学习另外三种性能优化的策略:     1. 采用对象池技术,提高对象的利用率 Java 中创建和释放对象会占

Android学习笔记之如何使用圆形菜单实现旋转效果...

PS:最近忙于项目的开发,一直都没有去写博客,是时候整理整理自己在其中学到的东西了... 学习内容: 1.使用圆形菜单并实现旋转效果..     Android的圆形菜单我也是最近才接触到,由于在界面中确实是使用到了,因此就去学习了一下圆形菜单的使用,并且实现菜单的旋转效果,类似于摩天轮那样的效果,个人感觉还是蛮不错的,就是在实现的过程中有点麻烦...通过动态加载的方式,使用ViewGroup来实现了这个过程...个人感觉是一个蛮复杂的过程,最后附上源码...上面先附上效果图,其实这个图给人的感

Android自定义View之仿QQ侧滑菜单实现

最近,由于正在做的一个应用中要用到侧滑菜单,所以通过查资料看视频,学习了一下自定义View,实现一个类似于QQ的侧滑菜单,顺便还将其封装为自定义组件,可以实现类似QQ的侧滑菜单和抽屉式侧滑菜单两种菜单. 下面先放上效果图: 我们这里的侧滑菜单主要是利用HorizontalScrollView来实现的,基本的思路是,一个布局中左边是菜单布局,右边是内容布局,默认情况下,菜单布局隐藏,内容布局显示,当我们向右侧滑,就会将菜单拉出来,而将内容布局的一部分隐藏,如下图所示: 下面我们就一步步开始实现一个

IOS开发UI篇--一个侧滑菜单SlidingMenu

一.简介 侧滑菜单已经成为app一个极常用的设计,不管是事务类,效率类还是生活类app.侧滑菜单因Path 2.0和Facebook为开发者熟知,国内目前也有很多流行app用到了侧滑菜单,比如QQ.网易邮箱.知乎等等.iOS官方并没有提供类似于侧滑栏之类的组件,所以我们需要自己写一个侧滑栏控件,为了不要重复造轮子,我在github上找到了一个使用简单方便,新手容易入手的侧滑菜单控件,地址:https://github.com/John-Lluch/SWRevealViewController/t

Android学习笔记(四七):Content Provider初谈和Android联系人信息

Content Provider 在数据处理中,Android通常使用Content Provider的方式.Content Provider使用Uri实例作为句柄的数据封装的,很方便地访问地进行数据的增.删.改.查的操作.Android并不提供所有应用共享的数据存储,采用content Provider,提供简单便捷的接口来保持和获取数据,也可以实现跨应用的数据访问.简单地说,Android通过content Provider从数据的封装中获取信息. Content provider使用Uri

【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用service提供很多功能,例如利用Google Maps API,现在我们将聚焦在HTTP serice中. Android SDK提供HttpClient,和J2EE中的接口非常相似.最常用的就是HTTP GET和HTTP POST.相关内容也可以阅读Android学习笔记(四五):互联网通信-Htt

Android学习笔记(第二篇)View中的五大布局

PS:人不要低估自己的实力,但是也不能高估自己的能力.凡事谦为本... 学习内容: 1.用户界面View中的五大布局... i.首先介绍一下view的概念   view是什么呢?我们已经知道一个Activity是Android的显示层,但是Activity是不能直接显示在屏幕上的,它也像JSP那样,显示的东西是html,那么Android也不例外,Activity是一个抽象的壳子,而显示的东西就是view或者是viewgroup(图形用户组件)....   有了这个概念,我们就清楚view是如何

android学习第1篇:windows下android环境搭建:adt-bundle

安卓学习开始了! 在windows上搭建安卓开发环境,看似简单,其实问题很多,我整整搭建了5天才搞定,当然,也是因为工作有些忙的原因,时间不太多,OK,本篇教程,我会将我遇到的所有问题都写上,希望看到这篇博客的朋友,不会犯同样的错误. 一.搭建JAVA开发环境 1.基本概念 如果你会JAVA,那直接略过就行. http://blog.csdn.net/alspwx/article/details/20799017 这篇博客,是我以前转载的别人的,主要是介绍:J2EE\J2ME\JVM\JRE\J