android drawerlayout用法,Android DrawerLayout

android drawerlayout用法,Android DrawerLayoutDrawerLayout 官方给我们提供的一个侧滑菜单控件 3 0 以后引入 为了兼容低版本 可以使用 v4 兼容包里的 DrawerLayout 随着 MaterialDesi 设计规范的发布 越来越多的应用用到了侧滑菜单的动画效果 Toolbar 和 DrawerLayout 的组合可以实现非常好的效果 首先来看下总体的效果 网易云音乐 App 网易云音乐 pngDrawerLay

DrawerLayout

DrawerLayout,官方给我们提供的一个侧滑菜单

控件,3.0以后引入。为了兼容低版本,可以使用v4兼容包里的DrawerLayout。随着Material Design设计规范的发布,越来越多的应用用到了侧滑菜单的动画效果。Toolbar和DrawerLayout的组合可以实现非常好的效果。

首先来看下总体的效果,网易云音乐App:

0026621c70bc

网易云音乐.png

DrawerLayout基本使用

一般情况下,DrawerLayout第一个子视图就是主内容布局,也就是打开App第一眼看到的布局;而第二个子视图就是侧滑菜单布局。区分这两个布局的关键属性android:layout_gravity.设置了这个属性的布局,就是侧滑菜单布局,而它的值决定了侧滑的方向。常规规范在编写布局文件时,第一个子布局是内容布局。

当android:gravity值为start|left时,侧滑菜单侧滑方式是左侧滑出;相反值为end|right时,侧滑菜单侧滑方式为右侧滑出。在编写主内容布局文件时,高宽必须是match_parent否则会报错

DrawerLayout activity布局文件

xmlns:android=”http://schemas.android.com/apk/res/android”

xmlns:app=”http://schemas.android.com/apk/res-auto”

android:id=”@+id/id_drawer_layout”

android:layout_width=”match_parent”

android:layout_height=”match_parent”

android:orientation=”vertical”>

android:layout_width=”match_parent”

android:layout_height=”match_parent”

android:orientation=”vertical”>

android:id=”@+id/id_drawer_layout_toolbar”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:background=”@color/light_menu_header”

android:minHeight=”?android:actionBarSize”

android:paddingTop=”@dimen/padding_top”

android:gravity=”center_vertical”

android:elevation=”4dp”

app:popupTheme=”@style/ThemeOverlay.AppCompat.Light”

app:theme=”@style/ThemeOverlay.AppCompat.Dark.ActionBar”

app:title=”@string/zhuhu_name”/>

android:id=”@+id/id_content”

android:layout_width=”match_parent”

android:layout_height=”match_parent”>

layout=”@layout/draw_menu_layout”/>

Drawerlayout Menu布局文件

xmlns:android=”http://schemas.android.com/apk/res/android”

android:layout_width=”280dp”

android:layout_gravity=”start”

android:layout_height=”match_parent”

android:clickable=”true”

android:orientation=”vertical”>

android:id=”@+id/id_draw_menu_header”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:background=”@color/light_menu_header”

android:orientation=”vertical”

android:paddingBottom=”10dp”

android:paddingTop=”@dimen/padding_top”>

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_marginLeft=”15dp”

android:layout_marginRight=”15dp”

android:orientation=”horizontal”>

android:layout_width=”36dp”

android:layout_height=”36dp”

android:background=”@drawable/ic_account_circle_white_24dp”/>

android:id=”@+id/id_draw_menu_item_login_tv”

android:layout_width=”match_parent”

android:layout_height=”36dp”

android:layout_marginLeft=”10dp”

android:gravity=”center_vertical”

android:text=”@string/draw_menu_item_login_tv”

android:textColor=”@android:color/white”

android:textSize=”18sp”/>

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:layout_marginTop=”15dp”

android:orientation=”horizontal”>

android:id=”@+id/id_draw_menu_item_backup”

android:layout_width=”0dp”

android:layout_height=”wrap_content”

android:layout_weight=”1″

android:drawableLeft=”@drawable/ic_star_white_24dp”

android:gravity=”center”

android:text=”@string/draw_menu_item_backup”

android:textColor=”@android:color/white”

android:textSize=”15sp”/>

android:id=”@+id/id_draw_menu_item_download”

android:layout_width=”0dp”

android:layout_height=”wrap_content”

android:layout_marginLeft=”20dp”

android:layout_weight=”1″

android:drawableLeft=”@drawable/ic_file_download_white_24dp”

android:gravity=”center”

android:text=”@string/draw_menu_item_download”

android:textColor=”@android:color/white”

android:textSize=”15sp”/>

android:id=”@+id/id_draw_menu_item_main_tv”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:background=”@color/light_menu_index_background”

android:paddingBottom=”10dp”

android:paddingLeft=”80dp”

android:paddingTop=”10dp”

android:text=”@string/draw_menu_item_main”

android:textColor=”@android:color/holo_blue_dark”

android:textSize=”18sp”

/>

android:id=”@+id/id_draw_menu_item_list_select”

android:layout_width=”match_parent”

android:layout_height=”match_parent”

android:background=”@android:color/white”

android:divider=”@android:color/transparent”

android:scrollbars=”none”>

上述布局文件中有两个关键属性:android:clickable和android:layout_width。将android:clickable设置为true是为了消费点击在DrawerLayout Menu Header布局上的事件(很多应用menu头部是一个图片,本身不能消费事件。这样事件就传递到了Menu布局下方的内容布局,会导致误操作)。android:layout_width属性决定了侧滑菜单的宽度,官方建议一般小于320dp。

0026621c70bc

DrawerLayout clickable false.gif

Activity中初始化

package android.example.com.toolbarusage;

import android.content.res.TypedArray;

import android.graphics.Color;

import android.os.Build;

import android.os.Bundle;

import android.support.annotation.Nullable;

import android.support.v4.content.ContextCompat;

import android.support.v4.widget.DrawerLayout;

import android.support.v7.app.ActionBarDrawerToggle;

import android.support.v7.app.AppCompatActivity;

import android.support.v7.widget.Toolbar;

import android.view.Menu;

import android.view.View;

import android.view.ViewGroup;

import android.view.Window;

/

* Created by syt on 16/10/16.

*/

public class ZhuHuDrawerActivity extends AppCompatActivity {

private Toolbar mToolbar;

private DrawerLayout mDrawerlayout;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

supportRequestWindowFeature(Window.FEATURE_NO_TITLE);

translucentStatusBar();

setContentView(R.layout.activity_drawer_layout);

initView();

}

private void initView() {

mToolbar = (Toolbar) findViewById(R.id.id_drawer_layout_toolbar);

//mToolbar.setMinimumHeight(calculateToolbarHeight());

//mToolbar.inflateMenu(R.menu.draw_layout_menu);

setSupportActionBar(mToolbar);

mToolbar.setNavigationIcon(R.mipmap.ic_drawer_home);

mDrawerlayout = (DrawerLayout) findViewById(R.id.id_drawer_layout);

//DrawerLayout监听器

ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(

this,

mDrawerlayout,

mToolbar,

R.string.app_name,

R.string.app_name

);

mDrawerlayout.addDrawerListener(toggle);

toggle.syncState();

}

private int calculateToolbarHeight() {

int idStatusBar = getResources().getIdentifier(“status_bar_height”, “dimen”, “android”);

int statusBarHeight = getResources().getDimensionPixelSize(idStatusBar);

TypedArray ta = obtainStyledAttributes(new int[]{android.R.attr.actionBarSize});

int actionBarHeight = ta.getDimensionPixelSize(0, 0);

return statusBarHeight + actionBarHeight;

}

/

* 实现5.0以上状态栏透明(默认状态是半透明)

*/

private void translucentStatusBar() {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

ViewGroup decorView = (ViewGroup) getWindow().getDecorView();

int option =

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;

decorView.setSystemUiVisibility(option);

getWindow().setStatusBarColor(ContextCompat.getColor(

getApplicationContext(),

R.color.light_menu_header

)

);

}

}

/

* 当使用setSupportActionBar()时,调用Toolbar.inflateMenu()时无效果,必须用此方法实现

* @param menu

* @return

*/

@Override

public boolean onCreateOptionsMenu(Menu menu) {

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

return true;

}

}

代码分析:先去除AppCompatActivity自带的ActionBar,通过findVewiById()获取到Toolbar空间对象后,调用setSupportActionBar()方法替换掉默认的ActionBar。这样操作之后又一个问题,直接调用Toolbar.inflateMenu()后Menu并没有显示出来,而是要通过onCreateOptionsMenu()去加载menu布局文件才可以实现效果。最后创建ActionBarDrawerToggle监听器,并且绑定DrawerLayout对象,实现监听侧滑菜单的显示和隐藏事件。同时适配了5.0以上的修改了状态栏颜色,保证Toolbar和DrawerLayout Menu实现状态栏的沉浸。

最终效果:

0026621c70bc

DrawerLayout.gif

ActionBarDrawerToggle

监听侧滑菜单事件可以使用DrawerLayout.DrawerListener,并重写相应的回调方法,实现监听相应的侧滑菜单栏状态的事件。那为什么用ActionBarDrawerToggle

ActionBarDrawerToggle,它是DrawerLayout.DrawerListener的具体实现类

ActionBarDrawerToggle是一个开关,用于打开/关闭DrawerLayout抽屉

ActionBarDrawerToggle 提供了一个方便的方式来配合DrawerLayout和ActionBar,以实现推荐的抽屉功能。即点击ActionBar的home按钮,即可弹出DrawerLayout抽屉。

虽然这里的demo用的是Toolbar,但是通过这个监听器,一样可以实现上述效果。我猜测原因是setSupportActionBar()方法的作用。

在Activity中的两个回调函数中使用它:

onConfigurationChanged,

onOptionsItemSelected。

调用ActionBarDrawerToggle.syncState() 在Activity的onPostCreate()中:指示,ActionBarDrawerToggle与DrawerLayout的状态同步,并将ActionBarDrawerToggle中的drawer图标设置为ActionBar的Home-Button的icon。

可以通过重写ActionBarDrawerToggle的onDrawerOpened()和onDrawerClosed()以监听抽屉拉出

或隐藏事件。

问题总结

DrawerLayout.setDrawerListener()

该方法已经废弃,可以使用addDrawerListener()。

setSupportActionBar()

调用此方法以后,原先加载的menu布局不显示,需要通过onCreateOptionsMenu()方法来实现。

DrawerLayout Menu状态栏沉浸

之前为了给Toolbar实现状态栏沉浸效果,将状态栏悬浮在DecorView之上,所以当滑出侧滑菜单栏时,状态栏遮挡住了一部分显示内容。解决方案就是给DrawerLayout Menu布局文件的header布局添加一个paddingTop属性,其值为状态栏高度。

误操作

给DrawerLayout Menu根布局设置android:clickable属性,其值设置为true。是为了消费点击在DrawerLayout Menu Header布局上的事件(很多应用menu头部是一个图片,本身不能消费事件。这样事件就传递到了Menu布局下方的内容布局,会导致误操作)。

参考

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/205755.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午5:16
下一篇 2026年3月19日 下午5:16


相关推荐

  • 虚拟机安装完linux后怎么使用linux_虚拟机ubuntu安装教程

    虚拟机安装完linux后怎么使用linux_虚拟机ubuntu安装教程本篇文章为本人从零开始学习linux的学习心得,其中包含了部署虚拟环境安装linux系统。其中若有错误之处,请读者积极指出,让本人与读者共同进步。第一章部署虚拟环境安装linux系统及配置网路一、linux简介首先在学习linux系统之前,我觉得应该先了解一下linux的来历和发展历程,会让我们对linux充满好奇心,对后续的学习会有帮助。(搬砖):早在20世纪70年代,…

    2022年10月8日
    5
  • “三门问题”的理解和Python验证

    “三门问题”的理解和Python验证三门问题 MontyHallpro 亦称为蒙提霍尔问题 蒙特霍问题或蒙提霍尔悖论 大致出自美国的电视游戏节目 Let sMakeaDeal 问题名字来自该节目的主持人蒙提 霍尔 MontyHall 参赛者会看见三扇关闭了的门 其中一扇的后面有一辆汽车 选中后面有车的那扇门可赢得该汽车 另外两扇门后面则各藏有一只山羊 当参赛者选定了一扇门 但未去开启它的时候 节目主持人

    2026年3月7日
    2
  • CSS常用水平垂直居中的几种方法

    CSS常用水平垂直居中的几种方法CSS 水平垂直居中一 利用 margin auto 二 利用 position absolute 三级目录一 利用 margin auto 元素有宽度和高度时 利用 margin auto 设置元素水平垂直居中 HTML 代码如下 divclass div1 divclass center CSS 代码如下 div1 background color eee width 200px hei divclass center divclass div1

    2026年3月18日
    2
  • SpringBoot 事务注解@Transactional

    SpringBoot 事务注解@TransactionalSpringBoot提供了非常方便的事务操作,通过注解就可以实现事务的回滚,非常方便快捷,下面我们就说一下如何进行事务操作。1.事务说明在Spring中,事务有两种实现方式,分别是编程式事务管理和声明式事务管理两种方式。编程式事务管理:编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,…

    2022年5月8日
    224
  • CC防御方案

    CC防御方案1DNS 高防方案 1DNS 高防需求 DNS 作为网络服务的入口 面临攻击的风险越来越大 传统的 DNS 服务基本不具备 DDOS 之类的防御能力 同时互联网上持续发生的 DDOS 攻击事件在不断的刷新着最大流量攻击纪录 所以提供可靠有效的 DNS 高防服务 其市场前景非常好 整体上 DNS 高防必需满足几个硬需求 对于同一个用户提供联通 电信两条线路的高防节点 支持大流量攻击下的防御 目标防御 5

    2026年3月26日
    2
  • 创建线程的三种方式优缺点

    创建线程的三种方式优缺点Java 使用 Thread 类代表线程 所有的线程对象都必须是 Thread 类或其子类的实例 一 继承 Thread 类创建线程类 1 重写 run 方法 该 run 方法的方法体就代表了线程需要完成的任务 2 创建 Thread 子类的实例 3 调用线程对象的 start 方法来启动该线程

    2026年3月26日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号