Drawerlyout添加监听以及点击事件穿透问题

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

Drawlayout是实现抽屉布局的关键,在上一篇文章中,我们介绍了怎么自定义抽屉布局。这次我们讲讲Drawlayout使用过程中经常碰到的问题

怎么更新抽屉中的列表

有时候,我们的抽屉布局中有列表,需要在页面初始化的时候加载数据。我们首先想到的也许就是在主页加载时就初始化抽屉列表,下面我们举个例子。

比如我们的抽屉布局中有个ListView

<android.support.v4.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/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <LinearLayout
        android:layout_width="160dp"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_gravity="end"
        android:background="#fff"
        android:fitsSystemWindows="true"
        android:paddingTop="30dp">

        <ListView
            android:id="@+id/lvListView"
            android:layout_width="160dp"
            android:layout_height="match_parent"
            android:dividerHeight="0dp"
            android:divider="@null"
            android:background="@null"/>

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>

然后我们会在主页Activity中加载布局时,初始化布局,包括抽屉布局

mListViewRight = (ListView) findViewById(R.id.lvListViewRight);
mListViewAdapter = new ListViewAdapter(this, items);
mListViewRight.setAdapter(mListViewAdapter);

接着我们会去拉取数据,然后更新我们的列表

items.add("new Item");
mListViewAdapter.notifyDataSetChanged();
添加监听,利用监听来根据需要更新

像上面更新抽屉数据的需求,我们也可以通过Drawlayout的监听事件来有需要的刷新,比如在抽屉打开的时候才刷新数据。

给Drawlyout添加监听也很简单,如下

mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
    @Override
    public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
    }

    @Override
    public void onDrawerOpened(@NonNull View drawerView) {
        
    }

    @Override
    public void onDrawerClosed(@NonNull View drawerView) {
    }

    @Override
    public void onDrawerStateChanged(int newState) {
    }
});

我们可以看到一共有4个接口回调,下面我们分别来看看

  • onDrawerSlide

从这名字就看得出来,这个是在Drawlayout滑动的过程中回调的,其中参数slideOffset表示抽屉滑动的比例,如果抽屉是慢慢打开的过程,slideOffset就是从0到1,反之就是从1到0了。

  • onDrawerOpened

看这名字,再看这英语中的“完成时态”,没错,这个接口在抽屉完全打开后调用

  • onDrawerClosed

这个同上,只不过是在抽屉完全关闭的时候调用

  • onDrawerStateChanged

这个是抽屉的状态改变时调用。抽屉一共有3个状态,分别是:打开、关闭和运动中。状态改变时都会调用这个接口。

利用监听接口更新抽屉

所以我们要更新抽屉布局的话,就可以利用这几个接口。比如要在抽屉打开的时候更新数据就可以在onDrawerOpened接口中做处理

if (mDrawer.isDrawerOpen(GravityCompat.START)) {
    updateData();
}

但是这种方式会有一个问题,就是抽屉打开的时候布局会闪一下。所以更好的方式是在onDrawerSlide中做处理

mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
    @Override
    public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
        //抽屉正在滑动时调用
        if (mDrawerLayout.isDrawerVisible(GravityCompat.START)) {
            //部分可见就会进入
            updateData();
        }
    }

    @Override
    public void onDrawerOpened(@NonNull View drawerView) {
        //抽屉完全打开后调用
    }

    @Override
    public void onDrawerClosed(@NonNull View drawerView) {
        //抽屉完全关闭后调用
    }

    @Override
    public void onDrawerStateChanged(int newState) {
    }
});

利用isDrawerVisible方法,当抽屉有部分可见时就会返回true,这样我们就可以在抽屉完全打开之前完成初始化的操作。

点击事件穿透

这个是很常见的一个坑了,刚刚碰到可能会一脸懵逼。但其实这个坑也很好填。

所谓点击事件穿透就是我们在点击抽屉布局时,点击事件被抽屉布局下面的主页面响应了,导致抽屉无法处理点击事件。

这个问题的原因其实就是事件机制了,有兴趣的可以去看看Drawlyout的事件处理部分的源码。

解决方法也很简单:在抽屉布局的根布局设置clickable属性为true就可以了

<android.support.v4.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/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
  
    //抽屉布局
    <LinearLayout
        android:layout_width="160dp"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_gravity="end"
        android:background="#fff"
        android:fitsSystemWindows="true"
        android:paddingTop="30dp"
        android:clickable="true">

       ...

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>

                       欢迎关注我的微信公众号,和我一起每天进步一点点!

AntDream

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值