当前位置:   article > 正文

android drawerlayout用法,Android DrawerLayout

android drawerlayout

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布局下方的内容布局,会导致误操作)。

参考

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/279569
推荐阅读
相关标签
  

闽ICP备14008679号