转载本专栏文章,请注明出处,尊重原创 。文章博客地址:道龙的博客

为了提高兴趣,咱们开头先看看最终要实现什么样的效果:

侧拉菜单在Android应用中非常常见,它的实现方式太多了,今天我们就说说使用Google提供的DrawerLayout来实现侧拉菜单效果。简单模仿一下网易客户端的侧边栏。

DrawerLayout的实现其实非常简单,可以说是“傻瓜式使用”。只要按照官方文档提供的步骤一步步实现,就没有太大的问题。

首先,我们对一个应用定义一个布局

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawerlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"> <!--中间布局--> <RelativeLayout
android:id="@+id/fragment_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"> <RelativeLayout
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#0cbfe8"> <ImageView
android:id="@+id/leftmenu"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/menu"/> <TextView
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_centerInParent="true"
android:gravity="center"
android:text="网易"/> <ImageView
android:id="@+id/rightmenu"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentRight="true"
android:padding="12dp"
android:src="@drawable/ic_action_user"/>
</RelativeLayout> <LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/title_bar"
android:orientation="vertical"/>
</RelativeLayout> <!--左侧的布局-->
<RelativeLayout
android:id="@+id/left"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="@android:color/white"> <!--这里通过listview放其他控件-->
<ListView
android:id="@+id/left_listview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</RelativeLayout> <!--右侧布局-->
<RelativeLayout
android:id="@+id/right"
android:layout_width="260dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:background="#62dec9"> <ImageView
android:id="@+id/p_pic"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_centerInParent="true"
android:src="@drawable/ic_action_user"/> <TextView
android:id="@+id/right_textview"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_below="@id/p_pic"
android:layout_centerHorizontal="true"
android:layout_marginTop="12dp"
android:text="个人中心"
android:textColor="@android:color/black"
android:textSize="14sp"/>
</RelativeLayout> </android.support.v4.widget.DrawerLayout>

首先,根布局就是DrawerLayout,在根布局之后又主要分为三大块(代码中描述了),第一块就是主界面的内容,第二块是左边拉出来的布局,第三块是右边拉出来的布局(一般应用只需要左侧布局)。那么系统怎么知道我们这个布局是主布局还是侧拉菜单的布局?请注意左边侧拉菜单布局android:layout_gravity="left"这个属性和右边菜单布局的android:layout_gravity="right"这个属性,我们必须指定这两个值才可以实现效果,系统通过layout_gravity属性的值来判断这个布局是左边菜单的布局还是右边菜单的布局,如果没有这个属性,只显示主界面的布局。

这个时候,让我们来运行一下程序看看效果:

布局文件写好之后,我们的侧拉效果其实就已经可以实现了,但是你发现左边拉出来什么东西都没有,那是因为还没有数据,所以我们要在MainActivity中初始化左边布局的ListView,给ListView赋值简直不能再简单的了,直接贴代码吧:

modeo类:

package com.itydl.drawerlayoutdemo;

public class ContentModel {

   private int imageView;
private String text;
private int id; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public ContentModel() {
} public ContentModel(int imageView, String text, int id) {
this.imageView = imageView;
this.text = text;
this.id = id;
} public int getImageView() {
return imageView;
} public void setImageView(int imageView) {
this.imageView = imageView;
} public String getText() {
return text;
} public void setText(String text) {
this.text = text;
} }

Adapter适配器:

package com.itydl.drawerlayoutdemo;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView; import java.util.List; public class ContentAdapter extends BaseAdapter { private Context context;
private List<ContentModel> list; public ContentAdapter(Context context, List<ContentModel> list) {
super();
this.context = context;
this.list = list;
} @Override
public int getCount() {
if (list != null) {
return list.size();
}
return 0;
} @Override
public Object getItem(int position) {
if (list != null) {
return list.get(position);
}
return null;
} @Override
public long getItemId(int position) {
return list.get(position).getId();
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHold hold;
if (convertView == null) {
hold = new ViewHold();
convertView = LayoutInflater.from(context).inflate(
R.layout.content_item, null);
convertView.setTag(hold);
} else {
hold = (ViewHold) convertView.getTag();
} hold.imageView = (ImageView) convertView
.findViewById(R.id.item_imageview);
hold.textView = (TextView) convertView.findViewById(R.id.item_textview); hold.imageView.setImageResource(list.get(position).getImageView());
hold.textView.setText(list.get(position).getText());
return convertView;
} class ViewHold {
public ImageView imageView;
public TextView textView;
} }

ListView子项布局:

<?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="horizontal"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:gravity="center"> <ImageView
android:id="@+id/item_imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"/> <TextView
android:id="@+id/item_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="aa"
android:textSize="20dp"/> </LinearLayout>

主活动代码。

public class MainActivity extends AppCompatActivity {

    private List<ContentModel> mList = new ArrayList<ContentModel>();;
private ListView mListView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData(); mListView = (ListView) findViewById(R.id.left_listview);
ContentAdapter adapter = new ContentAdapter(this,mList);
mListView.setAdapter(adapter); } private void initData() { mList.add(new ContentModel(R.drawable.doctoradvice2, "新闻", 1));
mList.add(new ContentModel(R.drawable.infusion_selected, "订阅", 2));
mList.add(new ContentModel(R.drawable.mypatient_selected, "图片", 3));
mList.add(new ContentModel(R.drawable.mywork_selected, "视频", 4));
mList.add(new ContentModel(R.drawable.nursingcareplan2, "跟帖", 5));
mList.add(new ContentModel(R.drawable.personal_selected, "投票", 6));
}
}

以上操作十分简单,就不想多做口舌了~

好了,给左边的侧拉菜单中的ListView赋值之后,把它拉出来,这下就全都有数据了。我们可以运行看看效果了:

模拟器运行测拉并不好控制,真机测试是比较完美的。同时,我们看到标题栏上边我加了一个按钮,那么我们能不能点击让左侧菜单拉出来呢?还有,我能不能给左侧的每一项item加上点击事假呢?答案是肯定的,最后,就让我们实现点击打开测拉菜单,以及实现左侧测拉菜单item的点击事件吧、

首先通过点击menu打开左侧边栏,点击个人图片打开个人中心。我们只需要给按钮添加点击事件就可以了:

menu事件

findViewById(R.id.leftmenu).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDrawerLayout.openDrawer(Gravity.LEFT);
}
});

个人事件:

findViewById(R.id.rightmenu).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDrawerLayout.openDrawer(Gravity.RIGHT);
}
});

其实很简单,直接调用DrawerLayout的openDrawer方法,参数传Gravity.LEFT表示让左边的侧拉菜单出来,参数如果传Gravity.RIGHT,则表示让右边的侧拉菜单出来。

完成了点击事件,我们就要想着点击item后要处理的事件了:

在这里再加入点击按钮切换指定页面的功能。即当我点击“新闻”,主界面显示新闻内容,当我点击”订阅“,主界面显示订阅的内容。这个也很好实现,首先,点击事件不用说,就是ListView的setOnItemClickListener,点击之后,我们的主界面会显示相应的Fragment。即,如果点击了新闻,则主界面显示新闻的Fragment,如果点击了订阅,则主界面显示订阅的Fragment,代码写了出来

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
//模拟两条数据 case 0://新闻
//切换新闻的Fragment
replaceFragment(new NewsFargment());
break;
case 1://订阅
//切换订阅的Fragment
replaceFragment(new SubscibeFragment());
break; default:
break;
}
//点击任一项item项,都关闭左侧菜单
mDrawerLayout.closeDrawer(Gravity.LEFT);
}
});

因为多个地方会用到切换Fragment,因此我又把这个功能封装了一个公共方法

public void replaceFragment(Fragment fragment){
//1、拿到FragmentManager管理器
FragmentManager manager = getSupportFragmentManager(); //2、获取事物
FragmentTransaction transaction = manager.beginTransaction(); //3、fragment的替换
transaction.replace(R.id.content,fragment); //4、提交事物
transaction.commit();
}

每次点击之后,就用相应的Fragment替换主界面的LinearLayout,当然,替换完成之后要记得关闭左边的侧拉菜单,传入的参数为Gravity.LEFT表示关闭左边的侧拉菜单,如果传入的菜单为Gravity.RIGHT表示关闭右边的侧拉菜单。这里两个Fragment都太简单了,我就不贴源码了。

我们还可以针对左侧测拉布局做一些效果,比如说是,点击选中色,不点击为默认色。以及加入一些其它的更绚丽的设置等。我这里就做简单的设置。更多的效果,大家可根据自己兴趣来。

针对这个需求我加入了下面的代码:

/**切换listview的item背景色,选中为红色;否则为黑色的方式二。当点击item的时候,就会触发子项item的焦点*/
mListView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus == true){
//获得焦点
mListView.setSelector(android.R.color.holo_red_light) ;
} else{
//失去焦点
mListView.setSelector(android.R.color.black) ;
}
}
});

项目开发完毕了,咱们来看看最终效果吧:

模仿网易新闻客户端测拉框架完毕,喜欢我的朋友可以关注我。

本文参考博客:1、http://blog.csdn.net/u012702547/article/details/49562747

2、http://www.cnblogs.com/mengdd/p/3213378.html

也可以打开微信搜索公众号  Android程序员开发指南  或者手机扫描下方二维码 在公众号阅读更多Android文章。

微信公众号图片:

Android Studio精彩案例(四)《DrawerLayout使用详解仿网易新闻客户端侧边栏 》的更多相关文章

  1. Android Studio精彩案例(一)《ActionBar和 ViewPager版仿网易新闻客户端》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 为了能更好的分享高质量的文章,所以开设了此专栏.文章代码都以Android Studio亲测运行,读者朋友可在后面直接下载源码.该专栏 ...

  2. Android Studio系列教程五--Gradle命令详解与导入第三方包

    Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...

  3. 类似掌盟的Tab页 Android 开源框架ViewPageIndicator 和 ViewPager 仿网易新闻客户端Tab标签 (转)

    原博客地址  :http://blog.csdn.net/xiaanming/article/details/10766053 本文转载,记录学习用,如有需要,请到原作者网站查看(上面这个网址) 之前 ...

  4. Android 开源框架ActionBarSherlock 和 ViewPager 仿网易新闻客户端

    转载请注明出处:http://blog.csdn.net/xiaanming/article/details/9971721 大家都知道Android的ActionBar是在3.0以上才有的,那么在3 ...

  5. Android 开源框架ViewPageIndicator 和 ViewPager 仿网易新闻客户端Tab标签

    转载请注明出处:http://blog.csdn.net/xiaanming/article/details/10766053 之前用JakeWharton的开源框架ActionBarSherlock ...

  6. Android SlidingMenu 仿网易新闻客户端布局

    前面两篇文章中的SlidingMenu都出现在左侧,今天来模仿一下网易新闻客户端左右两边都有SlidingMenu的效果,以下是网易新闻客户端效果: 不扯闲话了,直接进入正题吧 frame_conte ...

  7. Android Studio精彩案例(七)《ToolBar使用详解<一>》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 本文参考博客:http://blog.csdn.net/h_zhang/article/details/51232773 http:/ ...

  8. Android Studio精彩案例(五)《JSMS短信验证码功能实现》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 很多应用刚打开的时候,让我们输入手机号,通过短信验证码来登录该应用.那么,这个场景是怎么实现的呢?其实是很多开放平台提供了短信验证功能 ...

  9. Android Studio中Git和GitHub使用详解

    一.Git和GitHub简述 1.Git 分布式版本控制系统,最先使用于Linux社区,是一个开源免费的版本控制系统,功能类似于SVN和CVS.Git与其他版本管理工具最大的区别点和优点就是分布式: ...

随机推荐

  1. 【转】Impala导出查询结果到文件

    [转载出处]http://blog.csdn.net/jobschen/article/details/68942574 想用impala-shell 命令行中将查询的结果导出到本地文件,想当然的以为 ...

  2. 用golang实现常用算法与数据结构——跳跃表(Skip list)

    背景 最近在学习 redis,看到redis中使用 了skip list.在网上搜索了一下发现用 golang 实现的 skip list 寥寥无几,性能和并发性也不是特别好,于是决定自己造一个并发安 ...

  3. ASP.NET Core + Docker +Jenkins 实现持续集成

    1.新建一个ASP.NET Core MVC应用程序: 2.将其上传到git: 3.建立Jenkins任务 (1)选择"新建任务",输入任务名称,选择"自由风格项目&qu ...

  4. python学习记录 - python3.x中如何实现print不换行

    python3.x中如何实现print不换行   大家应该知道python中print之后是默认换行的, 那如何我们不想换行,且不想讲输出内容用一个print函数输出时,就需要改变print默认换行的 ...

  5. HDU3389 Game

    Problem Description Bob and Alice are playing a new game. There are n boxes which have been numbered ...

  6. [HEOI2015]小Z的房间

    Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. ...

  7. 無名(noname)

    [问题描述] 因为是蒯的题所以没想好名字,为什么要用繁体呢?去看<唐诗三百首>吧! 题意很简单,给你一个串,求他有多少个不同的子串,满足前缀为A,后缀为B. 需要注意的是,串中所有的字母都 ...

  8. [BZOJ]1089 严格n元树(SCOI2003)

    十几年前的题啊……果然还处于高精度遍地走的年代.不过通过这道题,小C想mark一下n叉树计数的做法. Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该 ...

  9. Tenka1 Programmer Contest D - IntegerotS

    Problem Statement Seisu-ya, a store specializing in non-negative integers, sells N non-negative inte ...

  10. 【Aho-Corasick automation 大米饼模板】

    自动机要打熟.自动机要打好.自动机要打得美妙. [例子:HDU2222] #include<stdio.h> #include<queue> #include<cstri ...