目录
一、介绍
安卓的DrawerLayout是一种布局容器,它允许用户通过从屏幕边缘水平或垂直滑动打开侧滑菜单。
二、使用
1、创建DrawerLayout视图布局
要创建一个DrawerLayout,我们首先需要在XML布局文件中定义视图层次结构。通常,我们将DrawerLayout作为根视图,并在其中添加两个子视图:主视图和侧拉菜单视图。下面是一个简单的示例:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 主视图 -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- 侧拉菜单视图 -->
<LinearLayout
android:id="@+id/menu_frame"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#FFFFFF">
<!-- 菜单项 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Menu Item 1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Menu Item 2"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Menu Item 3"/>
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
在这个布局中,我们定义了一个DrawerLayout作为根视图。主视图是一个FrameLayout,可以用来展示应用程序的主要内容。侧拉菜单是一个宽度为240dp的LinearLayout,在左侧贴着屏幕并呈现在主视图之上。当用户滑动屏幕时,我们可以使用Gravity.START将菜单帧放置在屏幕左侧。
2、在代码中操作DrawerLayout
一旦我们有了布局,我们就可以开始在代码中操作DrawerLayout。首先,我们需要获取对DrawerLayout的引用:
DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
接下来,我们可以通过使用以下方法来配置DrawerLayout:
setDrawerListener(DrawerListener listener)
:设置DrawerLayout的监听器。setDrawerLockMode(int lockMode, View drawerView)
:锁定DrawerLayout的状态(打开或关闭)。openDrawer(View drawerView)
:打开指定的抽屉页面。closeDrawer(View drawerView)
:关闭指定的抽屉页面。
例如,如果我们想要在用户打开或关闭侧边栏时执行一些逻辑,我们可以实现一个DrawerListener。该监听器具有四种回调方法:onDrawerClosed()、onDrawerOpened()、onDrawerSlide()和onDrawerStateChanged()。下面是一个简单的例子:
drawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
}
@Override
public void onDrawerOpened(View drawerView) {
// 打开侧边栏时执行的逻辑
}
@Override
public void onDrawerClosed(View drawerView) {
// 关闭侧边栏时执行的逻辑
}
@Override
public void onDrawerStateChanged(int newState) {
}
});
最后,我们需要确保用户可以使用按钮或手势打开侧边栏。要实现这一点,我们可以将Actionbar中的home按钮替换为导航按钮,并在按下它时打开侧边栏。还可以通过在MainActivity的onOptionsItemSelected()方法中添加以下逻辑来响应导航按钮的点击事件:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// 打开侧边栏
drawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
在这里,我们首先检查用户是否按下了home键。如果是,则使用openDrawer()方法打开位于屏幕左侧的菜单视图。
3、总结:
DrawerLayout是一种非常有用的布局容器,它使用户可以轻松地访问应用程序中的导航和设置。要使用DrawerLayout,我们需要创建一个包括主视图和侧滑菜单视图的XML布局,并在代码中操作DrawerLayout对象。最后,我们还需要确保用户可以使用手势或按钮打开侧拉菜单。
三、例子:
效果图:
MainActivity:
package com.example.drawerlayoutdemo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.drawerlayout.widget.DrawerLayout;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private DrawerLayout mDrawerLayout;
private LinearLayout mLinearLayout;
private Button leftBtn,rightBtn;
private TextView close_left_tv,close_right_tv;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
// 创建菜单栏
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
// 菜单的选中事件
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.setting1:
// 弹出一个对话框
Toast.makeText(this, "点击了设置", Toast.LENGTH_SHORT).show();
break;
case R.id.setting2:
Toast.makeText(this, "点击了工具", Toast.LENGTH_SHORT).show();
}
return true;
}
private void initView() {
mDrawerLayout = this.findViewById(R.id.drawer_menu);
mLinearLayout = this.findViewById(R.id.linearlayout);
leftBtn = findViewById(R.id.open_left_drawer);
rightBtn = findViewById(R.id.open_right_drawer);
close_left_tv = findViewById(R.id.close_left_drawer);
close_right_tv = findViewById(R.id.close_right_drawer);
close_right_tv.setOnClickListener(this);
close_left_tv.setOnClickListener(this);
rightBtn.setOnClickListener(this);
leftBtn.setOnClickListener(this);
//侧滑监听
mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
//设置拉出布局的宽度
mLinearLayout.setX(slideOffset * drawerView.getWidth());
Log.e(TAG, "onDrawerSlide: " + "滑动时执行");
Log.e(TAG, "onDrawerSlide偏移量: " + slideOffset);
Log.e(TAG, "onDrawerSlide偏移的宽度: " + drawerView.getWidth());
}
// 打开侧滑菜单时调用
@Override
public void onDrawerOpened(@NonNull View drawerView) {
}
// 关闭打开侧滑菜单时调用
@Override
public void onDrawerClosed(@NonNull View drawerView) {
}
// 当菜单状态发生改变时调用
@Override
public void onDrawerStateChanged(int newState) {
}
});}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.open_left_drawer:
mDrawerLayout.openDrawer(Gravity.LEFT);
break;
case R.id.open_right_drawer:
mDrawerLayout.openDrawer(Gravity.RIGHT);
break;
case R.id.close_right_drawer:
mDrawerLayout.closeDrawer(Gravity.RIGHT);
Toast.makeText(this, "关闭了右边的菜单!", Toast.LENGTH_SHORT).show();
break;
case R.id.close_left_drawer:
mDrawerLayout.closeDrawer(Gravity.LEFT);
Toast.makeText(this, "关闭了左边的菜单!", Toast.LENGTH_SHORT).show();
break;
}
}
}
activity_main:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_menu"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/open_left_drawer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="打开左侧滑" />
<Button
android:id="@+id/open_right_drawer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="打开右侧滑" />
</LinearLayout>
<LinearLayout
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:clickable="false"
android:orientation="vertical">
<include layout="@layout/layout_left" />
</LinearLayout>
<LinearLayout
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:clickable="false"
android:orientation="vertical">
<include layout="@layout/layout_right" />
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
layout_left和layout_right一样:
<?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:background="#fff"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/close_left_drawer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="50dp"
android:drawablePadding="10dp"
android:drawableTop="@mipmap/ic_launcher"
android:text="左侧菜单" />
</LinearLayout>
在res下创建menu,在menu下创建main.xml
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/setting1"
android:title="设置"/>
<item
android:id="@+id/setting2"
android:title="工具"/>
</menu>