1. 程式人生 > >Drawerlyout新增監聽以及點選事件穿透問題

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