引言
本文通過自定義布局將DrawerLayout
和material-menu
封裝起來,使在項(xiàng)目中使用更方便。這里面用到了DrawerLayout菜秦、material-menu异袄、Toolbar,可以參考一些博文了解:
創(chuàng)建自定義view
由于向Toolbar或ListView這樣的部件將會在不同的Activity中多次出現(xiàn)冤灾,為了提高代碼的重用率前域,這里將它們單獨(dú)放到部件文件中,用到時用include
引用(當(dāng)然也可以在BaseActivity中部署韵吨,然后讓用到的都繼承BaseActivity)匿垄。這里創(chuàng)建一個MaterialDrawerLayout
布局組件來進(jìn)行封裝。
自定義Toolbar
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.v7.widget.Toolbar>
自定義FrameLayout
<?xml version="1.0" encoding="utf-8"?>
<!--DrawerLayout 下面的Fragment-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
自定義Listview
<?xml version="1.0" encoding="utf-8"?>
<!-- 側(cè)滑欄 -->
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listView_drawer"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/white"
android:choiceMode="singleChoice"
android:divider="@color/item_normal_divider"
android:dividerHeight="0.4px" />
為導(dǎo)航欄的Item創(chuàng)建布局
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textColor="@color/drawer_item"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"/>
創(chuàng)建MaterialDrawerLayout布局
通過創(chuàng)建布局類的方式來創(chuàng)建自定義布局归粉,這里創(chuàng)建一個MaterialDrawerLayout
布局類椿疗,使他繼承DrawerLayout
,這這個類中主要完成DrawerLayout
和Toolbar
的綁定工作糠悼、對Toolbar
的導(dǎo)航按鈕的監(jiān)聽(導(dǎo)航抽屜的打開個關(guān)閉事件監(jiān)聽)以及對導(dǎo)航抽屜中的Item的點(diǎn)擊事件的監(jiān)聽和處理届榄。
創(chuàng)建構(gòu)造函數(shù)
這里實(shí)現(xiàn)了三個構(gòu)造函數(shù),其主要作用就是將該布局的父Activity
的上下文環(huán)境Context
傳進(jìn)來倔喂。
public MaterialDrawerLayout(Context context) {
this(context, null);
}
public MaterialDrawerLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MaterialDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
}
初始化ListView
<string-array name="drawer_menu">
<item>Menu 1</item>
<item>Menu 2</item>
<item>Menu 3</item>
<item>Menu 4</item>
</string-array>
這里使用strings.xml中的string數(shù)組資源做數(shù)據(jù)铝条。
/**
* 初始化側(cè)欄標(biāo)簽,并且為ListView Item的點(diǎn)擊事件設(shè)置監(jiān)聽器
*/
private void initDrawerList(){
mDrawerListView = (ListView)findViewById(R.id.listView_drawer);
// 從strings.xml中獲取數(shù)據(jù)
String [] items = getResources().getStringArray(R.array.drawer_menu);
// 生成適配器
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
mContext, R.layout.drawer_list_item, items);
// 為ListView設(shè)置適配器
mDrawerListView.setAdapter(adapter);
// 為ListView Item設(shè)置監(jiān)聽器
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
});
}
/**
* 對導(dǎo)航抽屜列表?xiàng)l目點(diǎn)擊的處理
* @param position
*/
private void selectItem(int position){
// add your code
this.closeDrawer(mDrawerListView);
}
這里順便為DrawerLayout的ListView的Item
設(shè)置了監(jiān)聽器,以及點(diǎn)擊處理席噩。
綁定toolbar
/**
* 將DrawerLayout和Toolbar綁定
* @param toolbar
*/
public void bindToolbar(Toolbar toolbar){
// 設(shè)置toolbar左上角的導(dǎo)航按鈕圖標(biāo)
mMaterialMenuDrawable = new MaterialMenuDrawable(
mContext, Color.WHITE, MaterialMenuDrawable.Stroke.THIN);
toolbar.setNavigationIcon(mMaterialMenuDrawable);
// 初始化導(dǎo)航抽屜列表
initDrawerList();
// 為導(dǎo)航抽屜的打開關(guān)閉事件設(shè)置監(jiān)聽
setListener(toolbar);
}
為導(dǎo)航按鈕設(shè)置監(jiān)聽
/**
* 為toolbar上的導(dǎo)航按鈕設(shè)置監(jiān)聽
* @param toolbar
*/
private void setListener(Toolbar toolbar){
mDarwerToggle = new ActionBarDrawerToggle(
(Activity) mContext, this, toolbar, R.string.drawer_open, R.string.drawer_close){
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
isDrawerOpened = false;
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
isDrawerOpened = true;
}
public void onDrawerStateChanged(int newState) {
if(newState == DrawerLayout.STATE_IDLE){
if (isDrawerOpened){
mMaterialMenuDrawable.setIconState(MaterialMenuDrawable.IconState.ARROW);
}else{
mMaterialMenuDrawable.setIconState(MaterialMenuDrawable.IconState.BURGER);
}
}
}
public void onDrawerSlide(View drawerView, float slideOffset) {
mMaterialMenuDrawable.setTransformationOffset(
MaterialMenuDrawable.AnimationState.BURGER_ARROW,
isDrawerOpened ? 2 - slideOffset : slideOffset);
}
};
this.setDrawerListener(mDarwerToggle);
}
將自定義MaterialDrawerLayout應(yīng)用到Activity中
首先隱藏項(xiàng)目的ActionBar
班缰,以便引入toolbar
,參考Toolbar的簡單使用悼枢。在activity_main.xml
中引入toolbar
以及materialdrawerlayout
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<!--Toolbar-->
<include layout="@layout/toolbar" />
<!--DrawerLayout-->
<com.example.customedrawerlayout.MaterialDrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--FragmentContent-->
<include layout="@layout/framelayout" />
<!--ListView-->
<include layout="@layout/listview_drawer" />
</com.example.customedrawerlayout.MaterialDrawerLayout>
</LinearLayout>
在MainActivity
中為toolbar
做些設(shè)置埠忘,然后調(diào)用MaterialDrawerLayout
的bindToolbar()
,如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDrawerLayout = (MaterialDrawerLayout)findViewById(R.id.drawer_layout);
mToolbar = (Toolbar)findViewById(R.id.toolbar);
// 將toolbar設(shè)為標(biāo)題欄
setSupportActionBar(mToolbar);
// 設(shè)置返回鍵可用
getSupportActionBar().setHomeButtonEnabled(true);
// 在Toolbar做最左邊加上導(dǎo)航按鈕
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerLayout.bindToolbar(mToolbar);
}
當(dāng)然最終要的一點(diǎn)是,不要忘了引入相應(yīng)的依賴莹妒。