使用DrawerLayout實現簡單的側滑效果
簡介
DrawerLayout是官方的一個實現側滑選單的控制元件,可以使用它實現大部分的側滑效果。
基本步驟
首先在佈局中使用DrawerLayout,它繼承自VIewGroup,第一個childView就是我們的內容佈局,第二個就是我們的選單,當然也可以有第三個作為第二個選單
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/ic_launcher" />
<ListView
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:tag="left"
android:background="#fff"/>
<ListView
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:tag="right"
android:background="#fff"/>
</android.support .v4.widget.DrawerLayout>
contentView自然是要填充父佈局,選單的width自己設定就好,值得一提的是選單的android:layout_gravity屬性,left表示左選單,right表示右選單這很直觀,還有一個start屬性,官方解釋如下
To support right-to-left (RTL) languages, specify the value with”start” instead of “left” (so the drawer appears on the right when the layout is RTL).
這樣就實現最基本的使用了,效果如下
listview沒有新增資料,背景圖片也圖省事直接用ic_laucnher,所以看起來比較醜。。。
設定監聽
官方提供了介面DrawerListener,監聽drawer的狀態,需要重寫以下四個個方法
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
}
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
@Override
public void onDrawerStateChanged(int newState) {
}
方法名已經很明顯了,在這就不解釋了,接下來我們利用這個介面實現一個側滑特效
程式碼如下
mDrawer.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// 判斷是否左選單
if (drawerView.getTag().equals("left")) {
// 得到contentView
View content = mDrawer.getChildAt(0);
int offset = (int) (drawerView.getWidth() * slideOffset);
content.setTranslationX(offset);
}
}
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
@Override
public void onDrawerStateChanged(int newState) {
}
});
這裡通過佈局檔案宣告的tag屬性來判斷是哪一個選單,如果是左選單,我們就在滑動過程中不斷設定content的translationX,這個值是根據選單的寬度和偏移比例相乘得到的,效果如下
稍加修改就可以實現qq的側滑效果
mDrawer.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// 判斷是否左選單
if (drawerView.getTag().equals("left")) {
// 得到contentView
View content = mDrawer.getChildAt(0);
int offset = (int) (drawerView.getWidth() * slideOffset);
content.setTranslationX(offset);
content.setScaleX(1 - slideOffset * 0.5f);
content.setScaleY(1 - slideOffset * 0.5f);
}
}
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
@Override
public void onDrawerStateChanged(int newState) {
}
});
}
使用ActionBarDrawerToggle
ActionBarDrawerToggle這個類實現了DrawerListener介面,它的作用就是配合ToolBar使用,這樣我們點選ToolBar的home鍵時,就可以出發drawer。當然,雖然ActionBarDrawerToggle幫我們重寫了四個方法,我們不需要重寫,我們也可以根據自己需要重寫相關方法,程式碼如下
mToolbar.setTitle("Test");
setSupportActionBar(mToolbar);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mToggle = new ActionBarDrawerToggle(this, mDrawer, mToolbar, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
View content = mDrawer.getChildAt(0);
if (drawerView.getTag().equals("left")) {
int offset = (int) (drawerView.getWidth() * slideOffset);
content.setTranslationX(offset);
content.setScaleX(1-slideOffset / 2);
content.setScaleY(1-slideOffset / 2);
}
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
//mToolbar.setTitle("closed");
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
//mToolbar.setTitle("opened");
}
};
mToggle.syncState();
mDrawer.addDrawerListener(mToggle);
ActionBarDrawerToggle的建構函式第一個是Activity,第二個是DrawerLayout,第三個是ToolBar,接下來兩個int我也不知道是什麼。mToggle.syncState()方法是同步toolbar與drawerlayout的狀態,也就是home的圖示會改變,最後當然就是新增監聽了,效果如下