引言
本文通过自定义布局将DrawerLayout
和material-menu
封装起来,使在项目中使用更方便。这里面用到了DrawerLayout、material-menu、Toolbar,可以参考一些博文了解:
- Toolbar的简单使用
- DrawerLayout的简单使用
- Toolbar+DrawerLayout+material-menu实现菜单侧滑
创建自定义view
由于向Toolbar或ListView这样的部件将会在不同的Activity中多次出现,为了提高代码的重用率,这里将它们单独放到部件文件中,用到时用include
引用(当然也可以在BaseActivity中部署,然后让用到的都继承BaseActivity)。这里创建一个MaterialDrawerLayout
布局组件来进行封装。
自定义Toolbar
自定义FrameLayout
自定义Listview
为导航栏的Item创建布局
创建MaterialDrawerLayout布局
通过创建布局类的方式来创建自定义布局,这里创建一个MaterialDrawerLayout
布局类,使他继承DrawerLayout
,这这个类中主要完成DrawerLayout
和Toolbar
的绑定工作、对Toolbar
的导航按钮的监听(导航抽屉的打开个关闭事件监听)以及对导航抽屉中的Item的点击事件的监听和处理。
创建构造函数
这里实现了三个构造函数,其主要作用就是将该布局的父Activity
的上下文环境Context
传进来。
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
- Menu 1
- Menu 2
- Menu 3
- Menu 4
这里使用strings.xml中的string数组资源做数据。
/**
* 初始化侧栏标签,并且为ListView Item的点击事件设置监听器
*/
private void initDrawerList(){
mDrawerListView = (ListView)findViewById(R.id.listView_drawer);
// 从strings.xml中获取数据
String [] items = getResources().getStringArray(R.array.drawer_menu);
// 生成适配器
ArrayAdapter adapter = new ArrayAdapter(
mContext, R.layout.drawer_list_item, items);
// 为ListView设置适配器
mDrawerListView.setAdapter(adapter);
// 为ListView Item设置监听器
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
selectItem(position);
}
});
}
/**
* 对导航抽屉列表条目点击的处理
* @param position
*/
private void selectItem(int position){
// add your code
this.closeDrawer(mDrawerListView);
}
这里顺便为DrawerLayout的ListView的Item
设置了监听器,以及点击处理。
绑定toolbar
/**
* 将DrawerLayout和Toolbar绑定
* @param toolbar
*/
public void bindToolbar(Toolbar toolbar){
// 设置toolbar左上角的导航按钮图标
mMaterialMenuDrawable = new MaterialMenuDrawable(
mContext, Color.WHITE, MaterialMenuDrawable.Stroke.THIN);
toolbar.setNavigationIcon(mMaterialMenuDrawable);
// 初始化导航抽屉列表
initDrawerList();
// 为导航抽屉的打开关闭事件设置监听
setListener(toolbar);
}
为导航按钮设置监听
/**
* 为toolbar上的导航按钮设置监听
* @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应用到Activity中
首先隐藏项目的ActionBar
,以便引入toolbar
,参考Toolbar的简单使用。在activity_main.xml
中引入toolbar
以及materialdrawerlayout
布局:
在MainActivity
中为toolbar
做些设置,然后调用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设为标题栏
setSupportActionBar(mToolbar);
// 设置返回键可用
getSupportActionBar().setHomeButtonEnabled(true);
// 在Toolbar做最左边加上导航按钮
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerLayout.bindToolbar(mToolbar);
}
当然最终要的一点是,不要忘了引入相应的依赖。