Android封装侧滑菜单栏

前言

Android开发过程中,我们有时会用到侧滑菜单栏的功能。在之前我已经写过一篇关于侧滑菜单栏的介绍,大家感兴趣的话,可以参看
Android实现侧滑菜单栏
为了方便使用,然后我将侧滑菜单栏的使用做了进一步封装,今天就来讲讲它的使用吧。

今天涉及内容:

  1. 侧滑菜单栏的依赖
  2. 封装类BaseMenuView简介
  3. BaseMenuViewActivity中使用
    3.1 编写自己的菜单栏控件 MenuView
    3.2 在 activity 中做 侧滑菜单的布局
    3.3 MenuView 在 Activity 中使用
    3.4 Activity代码
  4. 效果图和项目结构图
  5. BaseMenuView源码

先来个效果图


效果图.gif

一. 侧滑菜单栏的依赖

要实现侧滑菜单栏功能,我们需要借助DrawerLayout,在app_modulebuild.gradle中添加DrawerLayout依赖如下:

dependencies {
    //其他引用省略
    //......

    //DrawerLayout
    implementation "androidx.drawerlayout:drawerlayout:1.1.0-alpha03"
}

二.封装类 BaseMenuView 简介

为了方便侧滑菜单栏的使用,我封装了一个基类—BaseMenuView,当你需要写一个侧滑菜单栏的时候,你可以继承BaseMenuView写自己的侧滑菜单控件。那么接下来,让我们熟悉下BaseMenuView中的一些主要方法。

    /***
     * 初始化
     *
     * @param drawerLayout activiy中 DrawerLayout 根布局对象
     * @param listener
     */
    public void init(DrawerLayout drawerLayout,OnDrawerListener listener)

    /**activity的onPostCreate方法中调用,防止手机切屏报错**/
    public void onPostCreate()

    /**activity的 onConfigurationChanged 方法中调用,防止手机切屏报错**/
    public void onConfigurationChanged(Configuration newConfig)

    /***
     *  开启/关闭 菜单栏手势滑动功能
     *
     * @param open:true-开启, false-关闭
     */
    public void setDrawerLockMode(boolean open)

    /***
     *  启用/关闭 所有菜单栏手势滑动功能
     *
     *  注:当界面中有多个侧滑菜单栏(即同时有左,右侧滑菜单栏)时,可以用此方法
     *     快速对多个侧滑菜单栏做统一控制
     *
     * @param open:true-开启, false-关闭
     */
    public void setAllDrawerLockMode(boolean open)

    /**打开菜单**/
    public void openDrawer()

    /**关闭菜单栏**/
    public void closeDrawer()

    /***
     * 判断侧滑菜单栏是否已经打开
     *
     * @return true:已经打开
     *         false:已经关闭
     */
    public boolean isDrawerOpen()

    /***
     * 设置菜单栏宽度
     *
     * @param scaleWidth 0<scaleWidth<1
     */
    public void setLayoutWidth(double scaleWidth)

    /***
     * 设置为左侧菜单栏
     *
     * 注:也可以在布局中给侧滑菜单控件设置 android:layout_gravity="start" //左菜单栏
     */
    public void setLeftMenu()

    /***
     * 设置为右侧菜单栏
     *
     * 注:也可以在布局中给侧滑菜单控件设置 android:layout_gravity="end" //右菜单栏
     */
    public void setRightMenu()

三. BaseMenuView 在 Activity 中使用

3.1 编写自己的菜单栏控件 MenuView

为了讲述方便,我会写一个简单的 侧滑菜单栏控件,此控件布局中只有一个TextView,然后菜单栏中此TextView中具备点击事件。
先继承BaseMenuView写一个MenuViewMenuView代码如下:

public class MenuView extends BaseMenuView{

    private TextView mTextView;

    public MenuView(Context context, AttributeSet attrs){
        super(context,attrs);

    }

    @Override
    public int getLayoutId() {
        return R.layout.menu_layout;
    }

    @Override
    public void initView() {
        mTextView=getView(R.id.tv);
    }

    @Override
    public void initData() {

    }

    /**获取TextView控件**/
    public TextView getTextView(){
        return mTextView;
    }

}

布局文件menu_layout.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/green">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="30dp"
        android:textSize="16sp"
        android:textColor="@color/black"
        android:text="我是侧滑菜单"/>

</androidx.constraintlayout.widget.ConstraintLayout>

这里需要注意的是menu_layout.xml文件的根布局一定要是ConstraintLayout

3.2 在 activity 中做 侧滑菜单的布局

activity中做侧滑菜单,则MainActivity的布局文件activity_main.xml中根布局为DrawerLayout,然后内容布局放在上面,菜单布局放下面(注:一定要把内容布局放最上面),且DrawerLayout的子控件最多为三个(一般为两个)。就像下面这样:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/mDrawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!--  内容页布局  -->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white">

       //其他代码省略
       //......        

    </androidx.constraintlayout.widget.ConstraintLayout>

    <!-- 侧滑菜单栏 -->
    <com.demo.MenuView
        android:id="@+id/menuLayout"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"/>

</androidx.drawerlayout.widget.DrawerLayout>

MainActivity中有两个侧滑菜单时,布局类似下面这样:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/mDrawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!--  内容页布局  -->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white">

       //其他代码省略
       //......        

    </androidx.constraintlayout.widget.ConstraintLayout>

    <!-- 侧滑菜单栏 1-->
    <com.demo.MenuView
        android:id="@+id/menuLayout"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"/>

    <!-- 侧滑菜单栏 2-->
    <com.demo.MenuView
        android:id="@+id/menuLayout"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"/>

</androidx.drawerlayout.widget.DrawerLayout>

然后菜单栏可以为做左侧滑菜单栏,也可以为右侧滑菜单栏,位置的设定的话,你可以在xml布局中的自定义菜单控件MenuView上设置layout_gravity属性,就像下面这样:

    <com.demo.MenuView
        android:id="@+id/menuLayout"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"/>

其中:

android:layout_gravity="start"  //表示设置左侧滑菜单栏
android:layout_gravity="end"    //表示设置右侧滑菜单栏

当然,你也可以在代码中设置MenuView显示位置,就像下面这样:

        //设置为左侧显示(此设置可以在xml中设置)
        menuView.setLeftMenu();
        //设置为右侧显示(此设置可以在xml中设置)
        menuView.setRightMenu();

ok,以上基本介绍完毕,然后给出activity_main.xml布局全部代码吧:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/mDrawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!--  内容页布局  -->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white">

        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginTop="30dp"
            android:textSize="16sp"
            android:textColor="@color/black"
            android:text="我是测试"/>

        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:textColor="@color/black"
            android:textSize="16sp"
            android:text="测试"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
    
    <!-- 侧滑菜单栏 -->
    <com.demo.MenuView
        android:id="@+id/menuLayout"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"/>

</androidx.drawerlayout.widget.DrawerLayout>
3.3 MenuView 在 Activity 中使用

现在我们已经继承BaseMenuView写了一个自定义侧滑菜单栏MenuView,那么在Activity中使用只需写以下代码即可实现侧滑菜单功能:

    //声明DrawerLayout布局  和 侧滑菜单控件
    private DrawerLayout mDrawerLayout;
    private MenuView menuView;

    //初始化布局和控件
    mDrawerLayout = findViewById(R.id.mDrawerLayout);
    menuView = findViewById(R.id.menuLayout);

    //侧滑菜单栏相关设置
    private void initData() {
        //初始化设置
        menuView.init(mDrawerLayout, new BaseMenuView.OnDrawerListener() {
            @Override
            public void opened(View drawerView) {
                LogUtil.i("=====打开菜单======");
            }

            @Override
            public void closed(View drawerView) {
                LogUtil.i("=====关闭菜单======");
            }
        });
        //设置侧滑菜单栏显示屏幕宽度(不设置则默认为屏幕宽度0.75)
        menuView.setLayoutWidth(0.5);
        //设置为左侧显示(此设置可以在xml中设置)
        menuView.setLeftMenu();
        //此为 menuView 控件内部功能示例
        menuView.getTextView().setText("大家好");
        menuView.getTextView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ToastUtil.shortShow("为啥点击我");
            }
        });
    }
    
    //重写activity的 onPostCreate 和 onConfigurationChanged 方法并调用menuView相关方法
    @Override
    public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onPostCreate(savedInstanceState, persistentState);
        menuView.onPostCreate();
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        menuView.onConfigurationChanged(newConfig);
    }
3.4 Activity代码

下面贴出MenuViewMainActivity中使用完整代码:

public class MainActivity extends AppCompatActivity {

    //声明DrawerLayout布局
    private DrawerLayout mDrawerLayout;
    private TextView mTv;
    private Button mBtn;

    //声明侧滑菜单控件
    private MenuView menuView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LogUtil.setDebug(true);

        initView();
        initData();
        setListener();
    }

    private void initView() {
        //mDrawerLayout布局初始化
        mDrawerLayout = findViewById(R.id.mDrawerLayout);
        mTv = findViewById(R.id.tv);
        mBtn = findViewById(R.id.btn);
        //侧滑菜单控件初始化
        menuView = findViewById(R.id.menuLayout);
    }

    private void initData() {
        //初始化设置
        menuView.init(mDrawerLayout, new BaseMenuView.OnDrawerListener() {
            @Override
            public void opened(View drawerView) {
                LogUtil.i("=====打开菜单======");
            }

            @Override
            public void closed(View drawerView) {
                LogUtil.i("=====关闭菜单======");
            }
        });
        //设置侧滑菜单栏显示屏幕宽度(不设置则默认为屏幕宽度0.75)
        menuView.setLayoutWidth(0.5);

        //设置为左侧显示(此设置可以在xml中设置)
        menuView.setLeftMenu();


        //此为 menuView 控件内部功能示例
        menuView.getTextView().setText("大家好");
        menuView.getTextView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ToastUtil.shortShow("为啥点击我");
            }
        });

    }

    private void setListener() {
        mBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //打开左侧菜单
                menuView.openDrawer();
            }
        });
    }

    @Override
    public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onPostCreate(savedInstanceState, persistentState);
        menuView.onPostCreate();
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        menuView.onConfigurationChanged(newConfig);
    }

}

四.效果图和项目结构图

效果图.gif
项目结构图.png

五. BaseMenuView 源码

下面给出BaseMenuView源码:

还有 28% 的精彩内容
©著作权归作者所有,转载或内容合作请联系作者
支付 ¥4.00 继续阅读
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,252评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,886评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,814评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,869评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,888评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,475评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,010评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,924评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,469评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,552评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,680评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,362评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,037评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,519评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,621评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,099评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,691评论 2 361

推荐阅读更多精彩内容