Android DrawerLayout 左右侧滑菜单

上一章节中我们使用 DrawerLayout 实现了单侧侧滑菜单,但其实很多 APP 都会实现双向侧滑菜单,即既可以左侧滑出,也可以右侧滑出

本章我们就来实现一个左右侧滑菜单吧

DrawerLayout 左右侧滑菜单

仔细回忆下上一章节实现的单侧侧滑菜单,我们可以想象出,左右侧滑菜单由三部分组成:中间的内容部分,左边的侧滑菜单部分,右边的侧滑菜单部分组成


  1. 创建一个 空的 Android 项目 cn.twle.android.DrawerLayout

  2. res/layout 目录下新建一个 activity_other.xml 布局用于 左侧菜单的按钮点击

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:textStyle="bold"
            android:text="我是通过左边侧滑打开的Activity"/>
    
    </LinearLayout>
    
  3. MainActivity.java 同目录下新建一个 OtherActivity.java

    package cn.twle.android.drawerlayout;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    
    public class OtherActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_other);
        }
    }
    
  4. res/layout 目录下新建一个 main_content.xml 布局用于显示主要的内容

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/tv_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"/>
    
    </RelativeLayout>
    
  5. MainActivity.java 同目录下新建一个 MainContentFragment.java

    package cn.twle.android.drawerlayout;
    
    import android.annotation.SuppressLint;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    @SuppressLint("ValidFragment")
    public class MainContentFragment extends Fragment {
    
        private TextView tv_content;
        private String strContent;
    
        public MainContentFragment(String strContent) {
            this.strContent = strContent;
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.main_content, container, false);
            tv_content = (TextView) view.findViewById(R.id.tv_content);
            tv_content.setText(strContent);
            return view;
        }
    }
    
  6. 创建左边的 Fragment ,在 res/layout 目录下新建 dl_left.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <Button
            android:id="@+id/btn_in_left"
            android:text="左边的按钮"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    
  7. MainActivity.java 目录下新建文件 LeftFragment.java

    package cn.twle.android.drawerlayout;
    
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.widget.DrawerLayout;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.Gravity;
    import android.view.ViewGroup;
    import android.widget.Button;
    
    public class LeftFragment extends Fragment{
    
        private DrawerLayout drawer_layout;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.dl_left, container, false);
    
            Button btn_in_left = (Button) view.findViewById(R.id.btn_in_left);
            btn_in_left.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    getActivity().startActivity(new Intent(getActivity(),OtherActivity.class));
                    drawer_layout.closeDrawer(Gravity.START);
                }
            });
            return view;
        }
    
        // 暴露给 Activity,用于传入 DrawerLayout,因为点击后想关掉 DrawerLayout
        public void setDrawerLayout(DrawerLayout drawer_layout){
            this.drawer_layout = drawer_layout;
        }
    }
    
  8. 创建右边的 Fragment ,在 res/layout 目录下新建 dl_right.xml

    <?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="#2F9AF2"
        android:gravity="center"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/btn_in_right"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="右边的按钮" />
    
    </LinearLayout>
    
  9. MainActivity.java 目录下新建文件 RightFragment.java

    package cn.twle.android.drawerlayout;
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.widget.DrawerLayout;
    import android.view.LayoutInflater;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    
    public class RightFragment extends Fragment implements View.OnClickListener{
    
        private DrawerLayout drawer_layout;
        private FragmentManager fManager;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.dl_right, container, false);
    
            view.findViewById(R.id.btn_in_right).setOnClickListener(this);
            fManager = getActivity().getSupportFragmentManager();
            return view;
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn_in_right:
                    MainContentFragment cFragment1 = new MainContentFragment("点击了右侧菜单项");
                    fManager.beginTransaction().replace(R.id.fly_content,cFragment1).commit();
                    drawer_layout.closeDrawer(Gravity.END);
                    break;
            }
        }
    
        public void setDrawerLayout(DrawerLayout drawer_layout){
            this.drawer_layout = drawer_layout;
        }
    
    }
    
  10. 修改 activity_main.xml

    <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <FrameLayout
                android:id="@+id/fly_content"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
    
        </LinearLayout>
    
        <fragment
            android:id="@+id/fg_left_menu"
            android:name="cn.twle.android.drawerlayout.LeftFragment"
            android:layout_width="300dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:tag="LEFT"
            tools:layout="@layout/dl_left" />
    
        <fragment
            android:id="@+id/fg_right_menu"
            android:name="cn.twle.android.drawerlayout.RightFragment"
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:layout_gravity="end"
            android:tag="RIGHT"
            tools:layout="@layout/dl_right" />
    
    </android.support.v4.widget.DrawerLayout>
    
  11. 最后修改 MainActivity.java

    package cn.twle.android.drawerlayout;
    
    import android.os.Bundle;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.widget.DrawerLayout;
    import android.support.v7.app.AppCompatActivity;
    import android.view.Gravity;
    import android.view.View;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.Button;
    import android.widget.FrameLayout;
    
    public class MainActivity extends AppCompatActivity {
    
        private DrawerLayout drawer_layout;
        private FrameLayout fly_content;
        private Button btn_right;
        private RightFragment fg_right_menu;
        private LeftFragment fg_left_menu;
        private FragmentManager fManager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            fManager = getSupportFragmentManager();
            fg_right_menu = (RightFragment) fManager.findFragmentById(R.id.fg_right_menu);
            fg_left_menu = (LeftFragment) fManager.findFragmentById(R.id.fg_left_menu);
            initViews();
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu){
    
            menu.add(1,1111,0,"打开右侧菜单");
    
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
    
            drawer_layout.openDrawer(Gravity.END);
            drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED,
                    Gravity.END);    //解除锁定
    
            return super.onOptionsItemSelected(item);
        }
    
        private void initViews() {
            drawer_layout = (DrawerLayout) findViewById(R.id.drawer_layout);
            fly_content = (FrameLayout) findViewById(R.id.fly_content);
    
            //设置右面的侧滑菜单只能通过编程来打开
            drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED,
                    Gravity.END);
    
            drawer_layout.setDrawerListener(new DrawerLayout.DrawerListener() {
                @Override
                public void onDrawerSlide(View view, float v) {
    
                }
    
                @Override
                public void onDrawerOpened(View view) {
    
                }
    
                @Override
                public void onDrawerClosed(View view) {
                    drawer_layout.setDrawerLockMode(
                            DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.END);
                }
    
                @Override
                public void onDrawerStateChanged(int i) {
    
                }
            });
    
            fg_right_menu.setDrawerLayout(drawer_layout);
            fg_left_menu.setDrawerLayout(drawer_layout);
        }
    }
    
  12. 修改 AndroidManifest.xml 添加 OtherActivity

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="cn.twle.android.drawerlayout">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".OtherActivity"></activity>
        </application>
    
    </manifest>
    

几点解释

  1. drawer_layout.openDrawer(Gravity.END);

    设置打开的哪个菜单

    1. START 代表左边
    2. END 代表右边
  2. drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED,Gravity.END)

    锁定右面的侧滑菜单,不能通过手势关闭或者打开,只能通过代码打开

    即调用 openDrawer() 方法

    drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED,Gravity.END);
    

    解除锁定状态,即可以通过手势关闭侧滑菜单

    最后在 drawer 关闭的时候调用

    drawer_layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.END);
    

    再次锁定右边的侧滑菜单

参考文档

  1. 官方文档 DrawerLayout

  2. 弘扬大神写过一篇: Android DrawerLayout 高仿 QQ5.2 双向侧滑菜单

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.