關於側滑選單,網上也有很多方案,最多的應該就是使用Android的開源庫SlideMenu,而本文主要Android自帶的側滑選單控制元件DrawerLayout
。
Android自帶的側滑選單,也就是再v4
包下DrawerLayout
控制元件。該控制元件簡單易用,先看下實現的效果圖。
左選單:
右選單:
使用DrawerLayout
可以實現左右側滑選單,接下來就是程式碼實現。
佈局檔案:
<?xml version="1.0" encoding="utf-8"?>
<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/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lwj.uiproject.DrawerLayoutActivity">
<LinearLayout
android:id="@+id/content_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffffff"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/content_tx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="內容"
android:textSize="20dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/left"
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#ffadadad"
android:orientation="vertical">
<ListView
android:id="@+id/draw_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<LinearLayout
android:id="@+id/right"
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="#ff0000"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="right"
android:textSize="40dp"/>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
複製程式碼
佈局使用android.support.v4.widget.DrawerLayout
作為根view,包含三個部分:內容,左選單,右選單。DrawerLayout
佈局最好是先佈局內容,然後佈局選單,否則可能出現效果不對。
關於選單佈局,左選單佈局使用android:layout_gravity="start"
標誌,而右選單使用android:layout_gravity="end"
標誌,內容不需要使用標誌。
Actviity檔案:
public class DrawerLayoutActivity extends AppCompatActivity {
private TextView mTextView;
private ListView mListView;
private ListAdapter mAdapter;
private List<String> data = new ArrayList<>();
private DrawerLayout mDrawerLayout;
private LinearLayout mLeftMenu;
private LinearLayout mRightMenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_draw_layout);
for (int i = 0; i < 20; i++) {
String text = "drawerLayoutItem--->"+i;
data.add(text);
}
mDrawerLayout = (DrawerLayout)this.findViewById(R.id.toolbar);
mTextView = (TextView)this.findViewById(R.id.content_tx);
mListView = (ListView)this.findViewById(R.id.draw_list);
mLeftMenu = (LinearLayout)this.findViewById(R.id.left);
mRightMenu = (LinearLayout)this.findViewById(R.id.right);
mAdapter = new ListAdapter(DrawerLayoutActivity.this,data);
mListView.setAdapter(mAdapter);
View view = (View) LayoutInflater.from(this).inflate(R.layout.headerlayout,null);
mListView.addHeaderView(view);
// mDrawerLayout.setDrawerListener//已棄用
mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
Log.i("tag","---------->"+slideOffset);
// 滑動的過程當中不斷地回撥 slideOffset:0~1
View content = mDrawerLayout.getChildAt(0);
View menu = drawerView;
float offset = 1-slideOffset;//1~0
if (drawerView == mLeftMenu){
content.setTranslationX(menu.getMeasuredWidth()*(1-offset));//0~width
}else{
content.setTranslationX(-(menu.getMeasuredWidth()*(1-offset)));//0~width
}
}
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
@Override
public void onDrawerStateChanged(int newState) {
}
});
// mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// @Override
// public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// mDrawerLayout.closeDrawers();
// mTextView.setText(data.get(position));
//
// }
// });
mAdapter.setOnItemOnclickListener(new ListAdapter.OnItemOnclickListener() {
@Override
public void onClike(String text) {
mDrawerLayout.closeDrawers();
mTextView.setText(text);
}
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && mDrawerLayout.isDrawerOpen(mDrawerLayout.getChildAt(1))) { //按下的如果是BACK,同時沒有重複
mDrawerLayout.closeDrawers();
return true;
}
return super.onKeyDown(keyCode, event);
}
// @Override
// public boolean onKeyDown(int keyCode, KeyEvent event) {
// if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && !mDrawerLayout.isDrawerOpen(mDrawerLayout.getChildAt(1))) { //按下的如果是BACK,同時沒有重複
// mDrawerLayout.openDrawer(mDrawerLayout.getChildAt(1));
// return true;
// }
// return super.onKeyDown(keyCode, event);
// }
}
複製程式碼
初始化,關於選單google推薦使用NavigationView
控制元件,使用NavigationView
和DrawerLayout
配套使用更友好。
這裡最重要的一點就是使用DrawerLayout.DrawerListener()
設定監聽,監聽的onDrawerSlide
方法,可以監聽到滑動的距離0-1
的變化,利用這個資料,我們可以做一些實現滑動效果,比如qq選單的滑動效果。
舊版本設定監聽的方法是:mDrawerLayout.setDrawerListener
,現在google的api已經不推薦使用了,推薦通過mDrawerLayout.addDrawerListener
方法設定監聽。
關於DrawerLayout更多的使用方法,可以檢視原始碼或者api。