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>
歡迎關注我的微信公眾號,和我一起每天進步一點點!